Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

QR code generation into scalable EPS with Java

Tags:

java

qr-code

I'm currently working on an app that use ZXing to generate QR code as image. Here is a simple example:

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.WriterException;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;

public class MyQREncoder {

    /**
     * @param args
     * @throws WriterException 
     * @throws IOException 
     * @throws FileNotFoundException 
     */
    public static void main(String[] args) throws WriterException, FileNotFoundException, IOException {
        String text = "Some text to encode";
        int width = 300;
        int height = 300;
        BitMatrix bitMatrix = new MultiFormatWriter().encode(text, BarcodeFormat.QR_CODE,width,height);
        String file = "plop.png";
        String format = "png";
        MatrixToImageWriter.writeToStream(bitMatrix, format, new FileOutputStream(new File(file)));
    }

}

This generate a PNG file with a flashable QRcode saying "Some text to encode".

My problem is, if I try to change format to eps, then I'd be given an empty file. The current solution we use is to convert the png file to eps through imagemagick convert utility. But the given EPS is just embedding the raw image, and do not scale well (especialy when printed).

Do someone know if there is any opensource solution (with Zxing or other) to build a scalable Eps file ? (or any vectorial format for instance)

like image 260
Nicocube Avatar asked May 28 '26 15:05

Nicocube


1 Answers

Edit: Here's a complete working solution in Java:

PrintStream psFile = /* Open file */;

final int blockSize = 4;

psFile.println("%!PS-Adobe-3.0 EPSF-3.0");
psFile.println("%%BoundingBox: 0 0 " + bitMatrix.getWidth() * blockSize + " " + bitMatrix.getHeight() * blockSize);

psFile.print("/bits [");
for(int y = 0; y < bitMatrix.getHeight(); ++y) {
    for(int x = 0; x < bitMatrix.getWidth(); ++x) {
        psFile.print(bitMatrix.get(x, y) ? "1 " : "0 ");
    }           
}
psFile.println("] def");

psFile.println("/width " + bitMatrix.getWidth() + " def");
psFile.println("/height " + bitMatrix.getHeight() + " def");

psFile.println(
        "/y 0 def\n" + 
        blockSize + " " + blockSize + " scale\n" + 
        "height {\n" +
        "   /x 0 def\n" +
        "   width {\n" +
        "      bits y width mul x add get 1 eq {\n" +
        "         newpath\n" +
        "         x y moveto\n" +
        "         0 1 rlineto\n" +
        "         1 0 rlineto\n" +
        "         0 -1 rlineto\n" +
        "         closepath\n" +
        "         fill\n" +
        "      } if\n" +
        "      /x x 1 add def\n" +
        "   } repeat\n" +
        "   /y y 1 add def\n" +
        "} repeat\n");
psFile.close();

What about just generating the PS file yourself? Something like this:

%!PS-Adobe-3.0 EPSF-3.0
%%BoundingBox: 0 0 288 288

/bits [0 0 1 0  1 0 1 1  0 1 1 0  1 1 0 0] def

/width 4 def
/height 4 def
/y 0 def

72 72 scale

height {
   /x 0 def
   width {
      bits y width mul x add get 1 eq {
         newpath
         x y moveto
         0 1 rlineto
         1 0 rlineto
         0 -1 rlineto
         closepath
         fill
      } if
      /x x 1 add def
   } repeat
   /y y 1 add def
} repeat

(Where of course you would fill in the defs at the top with your own values, iterating through the BitMatrix and printing 1's and 0's to fill in bits) ps file output

like image 73
Russell Zahniser Avatar answered May 30 '26 05:05

Russell Zahniser



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!