Google Charts API zum Erstellen von QR-Codes nutzen

QR-Codes lassen sich automatisiert mit der Google Charts API erstellen (Screenshot Google Charts API Website + Bildmanipulation)

QR-Codes lassen sich automatisiert mit der Google Charts API erstellen (Screenshot Google Charts API Website + Bildmanipulation)

Google macht ja bekanntlich eine ganze Reihe spannender Produkte, von denen man den überwiegenden Teil kostenfrei nutzen kann. In diese Kerbe schlägt auch Google Charts, eine Online-Tool zum Erstellen allerlei ansehnlicher Diagramme zum Visualisieren von Daten. Durch die Nutzung der Google Charts API kann man das praktischen Helferlein auch in eigenen Projekten verwenden, zum Beispiel – und darum soll es in diesem Artikel gehen – zur Erstellung von QR-Codes. Im konkreten Beispiel nutze ich die API, um automatisiert mehrere vCard-QR-Codes auf Basis einer CSV-Datei zu erstellen. Aber dazu später mehr.

Warum überhaupt QR-Codes?

Wer die letzten Jahre nicht gerade in einer Höhle verbracht hat, dem sollten die quadratischen Pixel-Codes auf unzähligen Produktverpackungen und Werbemitteln nicht entgangen sein. Während Sie in Fernost – so sagt man – wohl schon lange ein Riesentrend sind, so haben die kleinen 2D-Codes mittlerweile auch uns vergleichsweise langsamen Mitteleuropäer erreicht. Genutzt werden Sie vorwiegend für einen Zweck: Informationen übertragbar und maschinenlesbar zu machen. Statt z.B. die lange Keyword-URL eines Unternehmes umständlich von deren Flyer abzutippen, scannt man einfach den Code mit seinem Smartphone – dieses erkennt die darin enthaltene URL und öffnet den Webbrowser mit dieser Adresse. Neben URLs können QR-Codes aber auch viele andere Informationen enthalten, beispielsweise E-Mail-Adressen, WiFi-Daten, Termine im iCalendar-Format oder eben auch Kontaktdaten einer Person im vCard-Format.

QR-Codes mit der Google Charts API

Das Erstellen von QR-Codes mit Google Charts ist sehr viel einfacher als man vielleicht denkt. Im Wesentlichen übergibt man einfach den gewünschten Inhalt an eine URL und bekommt anschließend einen fertigen QR-Code als PNG-Datei zurückgeliefert. Die URL  (für einen 500×500 Pixel großen QR-Code) lautet:

http://chart.apis.google.com/chart?chs=500x500&cht=qr&chld=L&chl={ZU-CODIERENDE-DATEN}

{ZU-CODIERENDE-DATEN} muß natürlich – ihr ahnt es sicher – gegen die zu codieren Daten ausgetauscht werden.

Beispiel 1: QR-Code einer URL

Nehmen wir mal an, wir möchten die URL zu diesem Blog codieren: Mit Angabe des Protokolls (wichtig!) wäre das „http://www.vektorkneter.de“. Um Strings, also Zeichenketten, aber an eine URL anzuhängen, muß man diese zuvor in eine besondere Form bringen und Sonderzeichen umwandeln. In PHP steht dafür die Funktion urlencode() zur Verfügung, in anderen Sprachen gibt es sicher ein vergleichbares Pendant. In unserem Beispiel bleiben wir aber bei PHP und nutzen den Service von functions online, um uns den String „http://www.vektorkneter.de“ für die Verwendung in der URL aufzubereiten. Das Ergebnis ist dann „http%3A%2F%2Fwww.vektorkneter.de“ und das hängen wir nun an die Google-Charts-URL:

http://chart.apis.google.com/chart?chs=500x500&cht=qr&chld=L&chl=http%3A%2F%2Fwww.vektorkneter.de

Gibt man diese URL nun im Browser der Wahl ein, erhält man den fertigen QR-Code von Google zurück. Glaubt ihr nicht? Probiert es aus.

Beispiel 2: QR-Code einer vCard

Was mit URLs geht, klappt nach dem gleichen Schema auch mit anderen Daten. Probieren wir das gleich noch mal mit Kontaktdaten im vCard-Format. Zu Testzwecken nehen wir hier die Beispiel-vCard von der Wikipedia-Seite zum vCard-Format:

BEGIN:VCARD
VERSION:3.0
N:Mustermann;Max
FN:Max Mustermann
ORG:Wikipedia
URL:http://de.wikipedia.org/
EMAIL;TYPE=INTERNET:max.mustermann@example.org
TEL;TYPE=voice,work,pref:+49 1234 56788
ADR;TYPE=intl,work,postal,parcel:;;Musterstraße 1;Musterstadt;;12345;Germany
END:VCARD

Das Ganze schicken wir nun einmal durch urlencode() auf functions online und erhalten folgenden String:

BEGIN%3AVCARD%0AVERSION%3A3.0%0AN%3AMustermann%3BMax%0AFN%3AMax+Mustermann%0AORG%3AWikipedia%0AURL%3Ahttp%3A%2F%2Fde.wikipedia.org%2F%0AEMAIL%3BTYPE%3DINTERNET%3Amax.mustermann%40example.org%0ATEL%3BTYPE%3Dvoice%2Cwork%2Cpref%3A%2B49+1234+56788%0AADR%3BTYPE%3Dintl%2Cwork%2Cpostal%2Cparcel%3A%3B%3BMusterstra%C3%9Fe+1%3BMusterstadt%3B%3B12345%3BGermany%0AEND%3AVCARD

Damit erzeugen wir jetzt die URL für die Anfrage an die Google Charts API. Die wird zwar reichlich unhandlich aber das stört nicht (die maximale Größe der Daten, die in einer URL an den Server übergeben werden können ist begrenzt – diese Länge hier ist aber kein Problem):

http://chart.apis.google.com/chart?chs=500x500&cht=qr&chld=L&chl=BEGIN%3AVCARD%0AVERSION%3A3.0%0AN%3AMustermann%3BMax%0AFN%3AMax+Mustermann%0AORG%3AWikipedia%0AURL%3Ahttp%3A%2F%2Fde.wikipedia.org%2F%0AEMAIL%3BTYPE%3DINTERNET%3Amax.mustermann%40example.org%0ATEL%3BTYPE%3Dvoice%2Cwork%2Cpref%3A%2B49+1234+56788%0AADR%3BTYPE%3Dintl%2Cwork%2Cpostal%2Cparcel%3A%3B%3BMusterstra%C3%9Fe+1%3BMusterstadt%3B%3B12345%3BGermany%0AEND%3AVCARD

Das war doch einfach, oder? Aber warum sollte man auf diese Weise QR-Codes erstellen, wo es doch eine ganze Reihe kostenloser QR-Code-Generatoren im Netz gibt (z.B. QRStuff)? Ganz einfach: Weil man mit der Google Charts API das Erstellen der QR-Codes klasse automatisieren kann.

QR-Codes automatisch auf Basis einer CSV-Datei erstellen (Stapelverarbeitung)

In einem Projekt hatte ich folgende Problemstellung: Auf einer (statischen) Website sollten die verschiedenen Teammitglieder jeder angeboten Produktsparte – in der Summe ca. 40 Personen – vorgestellt werden. Neben dem Bild der Person und den Kontaktdaten sollte jeweils auch ein QR-Code platziert werden, um Nutzern der Site zu erlauben, Kontaktdaten ausgewählter Teammitglieder unkompliziert in ihr Smartphone zu übertragen. 40 QR-Codes händisch über einen der kostenlosen QR-Code-Generatoren zu erzeugen, ist allerdings nicht unbedingt ein Riesenspaß. Eher im Gegenteil. Daher musste eine Lösung her, die im Idealfall die vom Kunden gelieferte Excel-Liste mit allen 40 Datensätzen in einem Rutsch „qr-codetisiert”. Also hab ich mir eine kleine Lösung in PHP geschrieben, die folgende Schritte automatisch durchführt:

  • Datensatz aus einer CSV-Datei holen
  • Datensatz ins vCard-Format bringen
  • vCard-Format-String via urlencode() für die URL nutzbar machen
  • Google-Chart-API-URL aufrufen
  • zurückgelieferte PNG-Datei des Codes benennen und abspeichern

Somit brauchte ich nur noch die Excel-Datei nach CSV zu exportieren (Unicode UTF-8, kommagetrennt), zusammen mit dem Skript auf einen PHP-fähigen Webserver (z.B. MAMP auf dem Mac) ablegen und das Skript aufrufen. PHP habe ich übrigens nur gewählt, weil ich mich damit hinreichend gut auskenne – wer das in leistungsfähigen oder Desktop-tauglicheren Sprachen umsetzen möchte: nur zu.

Download des Skriptes

Zum Selbertesten, Ausprobieren und Weiterentwickeln, hab ich das Skript zusammen mit einer Muster-CSV-Datei (mit Phantasienamen) in ein Paket gepackt, welches nachfolgend herunter geladen werden kann. Bitte beachtet vor der Nutzung des Skriptes die Google API-Nutzungsbedingungen. Und nutzt zum Testen nicht unbedingt hochprivate Kontaktdaten – auch wenn diese laut den Security & Privacy Informationen nur kurz zu Debugging-Zwecken gespeichert bleiben und nicht an Dritte übertragen werden (außer bei gesetzlich verpflichtenden Anfragen von z.B. Strafverfolgungsbehörden etc. wie Google im genannten Dokument beschreibt).

So gehts: Inhalt des ZIP-Archivs entpacken und auf den Server übertragen, Daten in die Datei adressen_utf8.csv eintragen (z.B. mit Open Office Calc) und anschließend die getcodes.php aufrufen. Die erzeugten Codes laden im Ordner /output.

Download: vCard-QR-Codes mit der Google Charts API (zipped, 5KB)

Das Skript ist nach besten Wissen getestet und erfüllt in meinem Szenario die gewünschten Anforderungen. Dennoch erfolgt die Nutzung des auf eigene Gefahr!
Die fertigen QR-Codes landen korrekt benannt im output-Ordner

Die fertigen QR-Codes landen korrekt benannt im output-Ordner

Allgemeine Anmerkungen zur Qualität von vCard-QR-Codes

Bei meinen Tests mit vCard-QR-Codes haben sich einige Besonderheiten oder Tücken gezeigt, auf die ich hier noch abschließend kurz eingehen möchte.

Darstellung der Kontaktdaten

Für die Darstellung der Kontaktdaten auf dem Smartphone ist in erster Linie die Code-Reader-App zuständig. In meinen Tests mit unterschiedlichen Apps hat sich gezeigt, dass viele Apps nicht in der Lage sind, Telefon- und Faxnummern zu unterscheiden, geschweige denn diese – wie im vCard-Format vorgesehen – als geschäftlich zu kennzeichnen. Vielmehr steht bei beiden Nummern oft nur „Zentrale”.
Auch die Adresse wird oftmals für deutsche Geflogenheiten unüblich dargestellt, nämlich mit der Postleitzahl nach (!) dem Ortsnamen. Dies hat vermutlich seine Wurzeln in der amerikanischen Adress-Schreibweise. Die besten Ergebnisse hatte ich unter iOS mit der App „QR Reader”, welche aber in dieser Form nicht mehr im App-Store zur Verfügung steht. Falls ihr eine App findet, die die Daten alle korrekt darstellt, würde ich mich über einen kurzen Hinweis freuen!

Lesbarkeit der QR-Codes

Die Dichte und Menge der Pixel innerhalb des QR-Codes steigt mit der Menge der im Code gespeicherten Informationen, logisch. Und je dichter die Pixel im Code angeordnet sind, desto schwieriger wird es für Kameras diese zu unterscheiden und den Code korrekt zu erkennen. Viele Online-QR-Code-Generatoren schreiben viele zusätzliche Meta-Informationen in das vCard-Format und erhöhen damit – unnötiger Weise – die Dichte der Pixel und verschlechtern somit die Lesbarkeit. Mein im Skript vorbereiteter Inhalt für das vCard-Format ist das Resultat aus etlichen Tests und brachte bei der Einbindung sämtlicher in der CSV-Datei vorgesehenen Informationen die besten Lese-Ergebnisse auf Low-End-Smartphones. Hier gilt ganz klar: Weniger ist mehr. Wenn ihr also z.B. keine Faxnummer in euren QR-Codes benötigt, dann werft die entsprechende Zeile komplett aus dem Skript, statt einfach nur ein leeres Feld zu schreiben.

Das solls an der Stelle auch zu diesem Thema gewesen sein. Fühlt euch frei, mein Skript zum Testen zu verwenden und nach Belieben zu modifizieren. Beachtet aber bitte die Google API-Nutzungsbedingungen – schließlich ist es der Google Charts Service, der hier die tatsächliche Arbeit leistet.

25 Kommentare Schreibe einen Kommentar

  1. Hallo,
    das Thema ist ja mal super spannend. Vielen Dank für die Vorlagen!

    Selber suche ich nach einer Lösung, welche ähnliches schaffen soll:
    Hinterlegt werden soll ein vollständiger Name mit einer dazugehörigen Nummer.
    Jetzt die weitere Frage. Wie benennt der Generator die Datei (Dateinamen).

    Ist es möglich hier ebenfalls Name – Nummer darzustellen?

    Excelliste:
    Ipsum Lorem
    D123456

    QR-Code (hinterlegt):
    D123456
    Ipsum Lorem

    Dateiname:
    Ipsum Lorem – D123456

    Kann man das in einer Automation beeinflussen?

    Ich freue mich auf eine hilfreiche Antwort : ))

    Vielen Dank und Gruß
    Philipp

    • Hallo Phillip,

      der Dateiname wird in Zeile 86 der getcodes.php festgelegt – in meinem Fall im Format [Lfd.Nummer].[Name].[Vorname].png. Das kannst Du dort natürlich nach Belieben Deinen Bedürfnissen anpassen.

  2. Hallo André,
    Genial, nur eine Frage, wie muss der Code aussehen, wenn nur ein Text / Nummer im QR Code generiert werden soll? Also keine VCard oder URl, nur Text aus der csv Datei? Irgendwie komme ich da nicht weiter…
    Danke schonmal für einen Hinweis
    Sarah

      • Hallo,
        ok, perfekt klappt wunderbar. Besten Dank für Deine schnelle Antwort. Gibt es noch eine Möglichkeit die PNG mit transparentem HG zu versehen und evtl nem dünneren Rand, der ist ja sehr breit…
        Liebe Grüße
        Sarah

        • Hallo,

          ok, soweit gelöst:
          Randbreite: chld=1 (1-4 möglich)
          Transparenz: chf=bg,s,65432100 – wobei nur der Rand transparent wird die weißen Flächen im Code bleiben weiß.
          so long
          Sarah

          • Hallo Sarah,
            danke dass Du Deine Erkenntnisse teilst – ich wusste z.B. nicht, dass man die Rahmenstärke der QR-Codes beeinflussen kann. Sehr interessant!

    • Hallo Bruno,

      mit dem QR-Code selbst kann man nicht steuern, wie dieser von der QR-Reader-App gehandhabt wird – also z.B. ob die im QR-Code kodierte URL direkt geöffnet wird. Der QR-Code transportiert nur Text, was damit passiert steuert die jeweilige App.

  3. Probiert doch mal die kostenlose App vom Erfinder des QR Codes, Denso Wave. Die wird von Arara.com vertrieben und steht in den jeweiligen App Stores kostenfrei zur Verfügung. Einen schnelleren und präziseren QR-Code Scanner habe ich noch nicht gefunden.

  4. Super Script aber wie kann ich die Daten in HTML auf meiner Homepage ausgeben ohne die komischen Pfeile und Zahlen? Ich möchte immer nur PLZ und Ort stehen haben. Gibt es dafür ein Tutorial?

    Liebe Grüße Conny

  5. Vielen Dank für den Beitrag hier. Hat mir echt geholfen. Ich versuche automatisiert QR-Codes zu erstellen und direkt zu verarbeiten. Das funktioniert auch, jedoch ist mir etwas aufgefallen, was eventuell für den ein oder anderen ganz hilfreich sein kann:

    Ich hatte bei Mitarbeitern verschiedene größen des Barcodes, obwohl immer 500×500 angegeben war in der URL. Der weiße Rand war einfach unterschiedlich. Da hat google anscheinend eine Skalierung hinterlegt. Wenn die URL > 503 Zeichen lang ist, mit der Ihr den Barcode erstellt, schrumpft das Bild – der weiße Rand wächst dadurch. Beim automatisierten Einbinden der Grafik wird der Barcode an sich somit kleiner.

    Vielleicht such der ein oder andere ja auch nach dem Problem/Fehler ;)

  6. Die Besten Ergebnisse erziele ich beim Lesen von QR Codes mit der App „Qrafter“.

    Diese erstellt in der Pro Version auch QR Codes als Vektoren aus Visitenkarten und speichert diese dann direkt in die Kontakte ab. Ich habe unter iOS ca. 10 Reader getestet und an diesem bin ich hängen geblieben…

  7. Endlich komm ich dazu mich zu bedanken. Dein Script funktioniert perfekt! Wenn du jemals was grafisches brauchst, meld dich einfach bei mir! schick dir meine kontaktdaten per mail!. lg selam

  8. Hi, super script. Ich bin in punkto scripten ein richtiger depp. :-) ist es recht schwierig dieses script so zu ändern, dass man nur internetadressen in die csv-datei eingibt. ich möchte musikstücke per qr-code downloadbar machen. danke aus dem tropischen österreich

      • Hui, das ging ja schnell. Probiers gleich aus, muss nur noch vorher eine Retusche fertig machen :-) Also in 2 stunden weiss ichs. Danke!!!!

  9. Okay danke!
    Sieht alles in Ordnung aus, komischerweise funktioniert es mit einer anderen App besser, als mit meiner, die es sonst immer ohne Probleme interpretieren konnte :)
    Naja aber wenigstens klappt es mit und ohne Mobilfunknummer!!!
    Vielen Dank noch mal für die Hilfe.

  10. Danke für die schnelle Antwort.
    Mein Code sieht nun wie folgt aus:

    //generating VCARD string
    $vcard = „BEGIN:VCARD\r\nVERSION:3.0\r
    FN:“ . $csv[$count][$title] . “ “ . $csv[$count][$forename] . “ “ . $csv[$count][$name] . „\r
    N:“ . $csv[$count][$name] . „;“ . $csv[$count][$forename] . „\r
    ORG:“ . $csv[$count][$organisation] . „\r
    TEL;TYPE=work,voice:“ . $csv[$count][$telephone] . „\r“;

    //generating VCARD string – 2. BLOCK – MIT DER BEDINGUNG
    if($csv[$count][$mobile] != „“){
    $vcard .= „TEL;TYPE=cell,voice:“ . $csv[$count][$mobile] . „\r“;
    }

    //generating VCARD string – 3. BLOCK
    $vcard .= „TEL;TYPE=work,fax:“ . $csv[$count][$telefax] . „\r
    URL;TYPE=work:“ . $csv[$count][$url] . „\r
    EMAIL;TYPE=work:“ . $csv[$count][$mail] . „\r
    ADR;TYPE=work:;;“ . $csv[$count][$street] . „;“ . $csv[$count][$city] . „;;“ . $csv[$count][$zip] . „;“. $csv[$count][$country]. „\r
    END:VCARD“;

    Der QR Code ist danach auch lesbar, jedoch zeigt er bei den Kontaktdaten nach der Telefonnummer aus Block 1 folgenden Text an „TEL;TYPE=work,fax“ , welcher aus dem Block 3 ist. Habe ich irgendeinen Fehler in meinem Script?

    • Das Problem deutet darauf hin, dass nach der Telefonnummer im Block 1 kein Zeilenumbruch eingefügt wird. Im VCARD-Format muss jeder Eintrag auf eine eigene Zeile, oder anders herum: Jeder Eintrag wird durch einen Zeilenumbruch beendet. So wie es aussieht, gib es also nach der Telefonnummer in Block 1 (wenn keine Mobilfunknummer vorhanden ist) keinen Zeilenumbruch und die Zeile mit der Faxnummer wird direkt hinten dran geklebt. Ich habe Deinen Code mal zum Testen kopiert – hier tritt das Problem nicht auf. Allerdings musste ich einige Anführungsstriche korrigieren, was aber evtl. an der Umwandlung durch mein Blogsystem liegt. Falsche Anführungsszeichen um den Zeilenumbruch (\r) könnten das Problem verursachen. Lass Dir am Besten mal den generierten VCARD-Code anzeigen. Dazu fügst Du einfach nach dem Code von Block 3 (also nach dem Semikolon) folgende Zeile ein: echo '<pre>'.$vcard.'</pre><hr />';
      Dann lässt Du das Skript laufen und schaust mal, ob an den Problemstellen tatsächlich die Umbrüche fehlen.

  11. Hallo,
    erstmal will ich mich für dieses wunderbare Script + Tutorial bedanken.
    Hat mir wirklich extrem geholfen und konnte es mit minimalen Aufwand für meine Bedürfnisse modifizieren.
    Ein klitzekleines Problem habe ich noch und ich dachte Sie könnten mir eventuell helfen.
    Ich habe eine Mobile Nummer hinzugefügt, jedoch hat nicht jeder eine, d.h. wenn dieses Feld leer an die GoogleAPI geschickt wird ist der QR Code unbrauchbar bzw. lässt sogar einen Reader abstürzen :D
    Gibt es eine Möglichkeit innerhalb des PHP Scriptes leere Felder in der CSV abzufangen?
    Zum Beispiel:
    Wenn $mobile = leer dann überspringe/ignoriere TEL;TYPE=cell,voice:“ . $csv[$count][$mobile] . „\r

    MFG Sascha

    • Hallo Sascha,
      im Original-Code wird ja der VCARD-Text innerhalb eines Blocks erzeugt. Da noch eine Bedingung rein zu hängen wird schwierig – ABER Du kannst ja diesen Block aufteilen:

      //generating VCARD string – 1. BLOCK
      $vcard = "BEGIN:VCARD\r\nVERSION:3.0\r
      N:" . $csv[$count][$name] . ";" . $csv[$count][$forename] . "\r
      ORG:" . $csv[$count][$organisation] . "\r
      TEL;TYPE=work,voice:" . $csv[$count][$telephone] . "\r
      TEL;TYPE=work,fax:" . $csv[$count][$telefax] . "\r";

      //generating VCARD string – 2. BLOCK – MIT DER BEDINGUNG
      if($csv[$count][$mobile] != ""){
      $vcard .= "TEL;TYPE=cell,voice:” . $csv[$count][$mobile] . “\r";
      }

      //generating VCARD string – 3. BLOCK
      $vcard .= "URL;TYPE=work:" . $csv[$count][$url] . "\r
      EMAIL;TYPE=internet,pref:" . $csv[$count][$mail] . "\r
      ADR;WORK:;;" . $csv[$count][$street] . ";" . $csv[$count][$city] . ";;" . $csv[$count][$zip] . ";". $csv[$count][$country]. "\r
      END:VCARD";

      Beachte denn Punkt vor dem Istgleichzeichen bei Block 2 und 3 ($vard .=) – der sorgt dafür, dass der nachfolgende String an den derzeitigen Inhalt der Variable $vard angehangen wird und diese nicht überschreibt. In Block 2 prüfen wir dann einfach, ob $csv[$count][$mobile] nicht leer ist und hängen – sofern das Feld Inhalt hat – die Zeile mit der Mobilnummer an den vorhanden Inhalt der Variable nach Block 1. In Block 3 folgt dann das Ende des VCARD-Inhaltes.

      Beste Grüße
      André

Schreibe einen Kommentar