** I am developing a Java Application for reading(decoding) QR Codes with out using camera in the laptop. I am using the ZXING JAR for the generation of QR Code.**
I am doing some manipulation for that QR Code. Now, I wanted to check whether the QR Code is fine or not with out using camera.
Is there any way it can be done?
ZXing has a JavaSE module which provides the crucial BufferedImageLuminanceSource for decoding a regular Java BufferedImage.
The bare minimum, extracted from ZXing's JavaSE DecodeThread:
BufferedImage image = ...
LuminanceSource source = new BufferedImageLuminanceSource(image);
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
Result result = new MultiFormatReader().decode(bitmap);
If decode() doesn't throw an exception, ZXing was able to decode the barcode (and you can check the contents of the bar code).
http://zxing.org/w/docs/javadoc/com/google/zxing/Reader.html#decode(com.google.zxing.BinaryBitmap, java.util.Map)
You can configure the MultiFormatReader, e.g. to only parse QR codes, by using the decode(BinaryBitmap, Map<DecodeHintType,?> hints) overload, allowing you to specify any number of decoding hints. Alternatively, if you really only want QR codes, use a QRCodeReader instead of MultiFormatReader.
Related
I've encountered this strange issue while trying to transfer images from my Java webserver to my Amazon S3 bucket. I am developing a mobile application for both Android and iOS (with Swift), which allows users to upload images from their device to the server.
The images (Bitmaps for Android, and UIImage for iOS) are both converted to Base 64 before being sent to my webserver (made in Java to conform to HTTP/1.1 standards). The data arrives to the server intact (meaning by printing the base 64 before it is sent, and after it arrives to the server, they are identical). From there I decode the String into a byte array. I have isolated the issue to have something to do with the actual sending process to the Amazon S3 bucket. Take the following snippet for example:
//image is a byte array, and imageid a String
InputStream is = new ByteArrayInputStream(image);
AmazonS3 s3 = new AmazonS3Client();
ObjectMetadata meta = new ObjectMetadata();
meta.setContentType("image/jpeg");
meta.setContentLength(image.length);
s3.putObject(new PutObjectRequest("bucket", "images/" + imageid + ".jpg", is, meta));
This code works fine for Android, where the images upload at 1080x1080 without an issue. However, when I try to upload an image from iPhone, the resolution becomes 1080x1081. Confused by this, I decided to try saving the image locally as well as send it to the server using ImageIO. Strangely enough, using:
BufferedImage img = ImageIO.read(new ByteArrayInputStream(image));
File f = new File("image.jpg"); //Removed file creation for brevity
ImageIO.write(img, "jpg", f);
When I used the "identify" command from Imagick on the local image, the output is:
image.jpg JPEG 1080x1080 1080x1080+0+0 8-bit DirectClass 53.4KB 0.000u 0:00.000
However when I transfer the image from the S3 bucket and do the same thing, I get:
image2.jpg JPEG 1080x1081 1080x1081+0+0 8-bit DirectClass 56.2KB 0.000u 0:00.000
Again, this only occurs with uploads from iOS. The image itself is still valid and opens without an issue. For example:
Face Down Camera Image
(Picture was taken while the camera was facing down, hence the dark image)
I suspect the issue may have something to do with differences in how the images are encoded into Base 64. I use the Bouncycastle library to do the encoding on Android, as well as the decoding on the webserver, and use an NSData function in swift as described below:
let imageData = UIImageJPEGRepresentation(normImg, 0.4)
let base64 = NSString(data: imageData!.base64EncodedDataWithOptions(NSDataBase64EncodingOptions(rawValue: 0)), encoding: NSUTF8StringEncoding) as! String
What confuses me the most is how ~3KB of data (which makes sense for 1080 extra pixels at 3 bytes per RGB pixel) seems to just be appearing out of nowhere, and why it seems to be isolated to iOS.
Hopefully I was clear enough with my question and the debugging I have done to provide as much information as possible. If you need any more information, please let me know!
Edit: Just ran a test and uploaded a 1080x1080 image by command line to the S3 bucket. It also adds the extra pixels.
Edit2: Decided to change how the file uploading process worked. It is no longer being converted to base 64, and the NSData of the UIImage is being converted into a byte (UInt8) array and uploaded. The still leads to the same result of having the extra pixel, which rules out my original speculation that it had something to do with the base64 encoding. Android still seems to function properly on the other hand, which leaves me to believe that the binary data of the image is not completely valid for whatever reason. I believe the EXIF data is formatted differently between Android and iOS, though I don't know what would cause this.
For our standard PDF & Barcode generation, we have the Java4Less library (java4less-1.0rel.jar) so that our customers can print tickets sold to/by them. We use this library to create CODE128(C), Aztec, QR barcodes and so on.
Right now we're looking into PDF417 Barcodes; and while this library supports this generation, something isn't going right. Have a look at the following code from a small Netbeans project:
BarCode bc= new BarCode();
bc.setSize(400 , 200);
bc.barType = BarCode.PDF417;
bc.resolution=1;
bc.leftMarginCM= 50;
bc.topMarginCM= 50;
bc.checkCharacter =true;
bc.code = "THISISJUSTATESTTEXT";
bc.barColor = Color.black;
bc.backColor= Color.red;
bc.fontColor = Color.blue;
bc.textFont = new Font("Arial",Font.BOLD,14);
bc.X = 1;
bc.N = 3;
bc.paint(region);
ImageIO.write(img, "PNG", new File("barcode.png"));
This piece of code generates a .png image with the requested barcode-type. All barcodes are generated, except for the PDF417.
Here's an image that shows a CODE128 and a PDF417 generation:
As you can see, the CODE128 generates its barcode, but the PDF417 doesn't. The only thing changed in the code is the following:
bc.barType = BarCode.CODE128; --> bc.barType = BarCode.PDF417;
I've looked up the documentation, examples; I even downloaded the demo from the official Java4Less website, and in a war/Java project, it generates a PDF417 normally.
So what is going wrong here? Is it a bug in the library that anyone knows of, or am I missing a step?
It would seem that our current library, despite claiming to support PDF417 creation, was outdated. When using the demo's library I managed to succesfully create a PDF417 barcode with the previousley mentioned code.
I make an Android app that captures a photo and saves the text from it using OCR. This is my code with Asprise library, but something is wrong with the "recognize" method:
Ocr.setUp();
Ocr ocr = new Ocr();
ocr.startEngine("eng", Ocr.SPEED_FASTEST);
String s = ocr.recognize(theImage, Ocr.RECOGNIZE_TYPE_ALL, Ocr.OUTPUT_FORMAT_PLAINTEXT);
ocr.stopEngine();
"theImage" is Bitmap, but they want "RenderedImage" type there (thought Bitmap is rendered too), and the fourth parameter of the "recognize" method is "Object... propSpec", but there in the sample of asprise official site there are only 3 parameters. And now parameters in the "recognize" line are underlined with red. So, what should I do with my code that it work properly?
P.S. Of course, I've heard about tess-two library, but it's a bit complicated for me to add it in Android Studio (I don't know why they couldn't just make it the way that it be added with only one line in build.gradle)
I've implemented same , what you want to do , by following code , and this is working as i wanted it to , other issues may be like file reader in your PC i.e, if you want PDF file to be OCR , .pdf reader should be installed .
Ocr.setUp();
Ocr ocr = new Ocr();
ocr.startEngine("eng", Ocr.SPEED_FASTEST);
String s = ocr.recognize(new File[] {new File(path)},
Ocr.RECOGNIZE_TYPE_ALL, Ocr.OUTPUT_FORMAT_PLAINTEXT);
System.out.println("Result: \n" + s);
ocr.stopEngine();
System.out.println("---END---");
so far i m trying
BufferedImage img = ImageIO.read(new ByteArrayInputStream(bytes));
but its give an error does don't support ImageIO in Apps engine.
The Image service Java API lets you apply transformations to images, The app prepares an Image object with the image data to transform, and a Transform object with instructions on how to transform the image, Check this link
byte[] oldImageData; // ...
ImagesService imagesService = ImagesServiceFactory.getImagesService();
Image oldImage = ImagesServiceFactory.makeImage(oldImageData);
Transform resize = ImagesServiceFactory.makeResize(200, 300);
Image newImage = imagesService.applyTransform(resize, oldImage);
byte[] newImageData = newImage.getImageData();
App Engine works in a sandbox, thus a lot of Java libraries are not accessible. For details, see this link [1].
The workaround provided in the other answer let's your buffer an image but it doesn't directly answer your question why you got the ImageIO error.
[1] - JRE whitelist for Google App Engine - https://cloud.google.com/appengine/docs/java/jrewhitelist
i have a problem in generating proper qr-codes with the zxing api.
I am able to generate a qr-code but when i read the qr-code then chars like "äü" arent displayed right.
code:
BitMatrix matrix = writer.encode(text, BarcodeFormat.QR_CODE, 200,200);
//text is String text = "geändert";
bufferedImage = MatrixToImageWriter.toBufferedImage(matrix);
If i start with "ü" then followed by "äö" then its displayed correct
anyone knows why?
You can read the QR Code from zxing api from below code.
binaryBitmap = new BinaryBitmap(new HybridBinarizer(new BufferedImageLuminanceSource(ImageIO.read(new FileInputStream("QR_Code.JPG")))));
result = new MultiFormatReader().decode(binaryBitmap);
System.out.println("QR Code : "+result.getText());
If you look at the developer documentation from zxing http://code.google.com/p/zxing/wiki/DeveloperNotes you will see that they expressly talk about the issue with non latin based characters.
As the QR Code standard does not define an exact way of specificing the character encoding within a QR code there recommendation is to only use characters which appear within all three standard encodings (ISO-8859-1, ISO-8859-15, UTF-8)
In the Hashtable of hints that you pass the encoder, set EncoderHintType.CHARACTER_SET to "UTF-8". Barry's answer is correct, but forcing it to try UTF-8 might happen to work better for you.
You can read the QR Code from zxing api from below code.
binaryBitmap = new BinaryBitmap(new HybridBinarizer(new BufferedImageLuminanceSource(ImageIO.read(new FileInputStream("QR_Code.JPG")))));
result = new MultiFormatReader().decode(binaryBitmap);
System.out.println("QR Code : "+result.getText());