Search code examples
javaqr-codezxingvector-graphics

Create QR-Code in vector image


I can successfully create QR Code PNG images with ZXing but there is no easy way to get the output as SVG or EPS.

How can I create a vector image from the BitMatrix object that is created by the QRCodeWriter?


Solution

  • The easiest way I found was to create a PDF with iText and then convert the resulting PDF to EPS or SVG. Here is the code to create the PDF:

       @Test
       public void testQRtoPDF() throws WriterException, FileNotFoundException, DocumentException, UnsupportedEncodingException {
          final int s = 600;
          int r = 1;
    
          Charset charset = Charset.forName( "UTF-8" );
          CharsetEncoder encoder = charset.newEncoder();
          byte[] b = null;
          try {
             // Convert a string to UTF-8 bytes in a ByteBuffer
             ByteBuffer bbuf = encoder.encode( CharBuffer.wrap(
                         "1éöàäèüùòïëéöàäèüùòïëéöàäèüùòïëéöàäèüùòïëéöàäèüùòïëéöàäèüùòïëéöàäèüùòïëéöàäèüùòïëéöàäèüùòïëéöàäèüùò1" +
                                     "2éöàäèüùòïëéöàäèüùòïëéöàäèüùòïëéöàäèüùòïëéöàäèüùòïëéöàäèüùòïëéöàäèüùòïëéöàäèüùòïëéöàäèüùòïëéöàäèüùò2" +
                                     "3éöàäèüùòïëéöàäèüùòïëéöàäèüùòïëéöàäèüùòïëéöàäèüùòïëéöàäèüùòïëéöàäèüùòïëéöàäèüùòïëéöàäèüùòïëéöàäèüùò3" +
                                     "4éöàäèüùòïëéöàäèüùòïëéöàäèüùòïëéöàäèüùòïëéöàäèüùòïëéöàäèüùòïëéöàäèüùòïëéöàäèüùòïëéöàäèüùòïëéöàäèüùò4" +
                                     "5éöàäèüùòïëéöàäèüùòïëéöàäèüùòïëéöàäèüùòïëéöàäèüùòïëéöàäèüùòïëéöàäèüùòïëéöàäèüùòïëéöàäèüùòïëéöàäèüùò5" +
                                     "6éöàäèüùòïëéöàäèüùòïëéöàäèüùòïëéöàäèüùòïëéöàäèüùòïëéöàäèüùòïëéöàäèüùòïëéöàäèüùòïëéöàäèüùòïëéöàäèüùò6" ) );
             b = bbuf.array();
          } catch ( CharacterCodingException e ) {
             System.out.println( e.getMessage() );
          }
    
          String content = new String( b, "UTF-8" );
          QRCodeWriter qrCodeWriter = new QRCodeWriter();
          Hashtable<EncodeHintType, String> hints = new Hashtable<EncodeHintType, String>( 2 );
          hints.put( EncodeHintType.CHARACTER_SET, "UTF-8" );
          BitMatrix qrCode = qrCodeWriter.encode( content, BarcodeFormat.QR_CODE, s, s, hints );
    
          Document doc = new Document( new Rectangle( s, s ) );
          PdfWriter pdfWriter = PdfWriter.getInstance( doc, new FileOutputStream( "qr-code.pdf" ) );
          doc.open();
          PdfContentByte contentByte = pdfWriter.getDirectContent();
          contentByte.setColorFill( BaseColor.BLACK );
    
          boolean d = false;
          for ( int x = 0; x < qrCode.getWidth(); x += r ) {
             for ( int y = 0; y < qrCode.getHeight(); y += r ) {
                if ( qrCode.get( x, y ) ) {
                   contentByte.rectangle( x, s - y, r, r );
                   contentByte.fill();
                   contentByte.stroke();
                }
             }
          }
    
          doc.close();
       }
    

    I then use image magic for the conversion. Like so:

    convert qr-code.pdf qr-code.eps
    

    the same can NOT be done for svg

    convert qr-code.pdf qr-code.svg
    

    this does not work

    I tested this code with some long content and it worked with up to 600 characters. This is probably down to the precision of either camera on the phone or screen.

    I hope this helps someone