We are using zxing to decode qrcode from images, most of qrcode could normally be extracted from the original images, but some not. I will show the decoder codes and shall we together discuss about what causes NotFoundException and find out solutions.
First of all, need some zxing dependencies:
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>core</artifactId>
<version>3.2.1</version>
</dependency>
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>javase</artifactId>
<version>3.2.1</version>
</dependency>
Then see the detail codes:
public static String decodeQrCode(BufferedImage image) throws DependencyServiceException
{
// Convert the image to a binary bitmap source
LuminanceSource source = new BufferedImageLuminanceSource(image);
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
// Decode the barcode
QRCodeReader reader = new QRCodeReader();
Result result = null;
try
{
result = reader.decode(bitmap);
}
catch (NotFoundException | ChecksumException | FormatException e)
{
throw new DependencyServiceException(e);
}
return result == null ? null : result.getText();
}
public static void main(String[] args)
{
File file = new File("/tmp/ivan_qr_code.jpg");
String qrCodeOriginUrlExtracted = "";
try
{
FileInputStream imageInFile = new FileInputStream(file);
byte imageData[] = new byte[(int) file.length()];
imageInFile.read(imageData);
String qrCodeBase64 = Base64.encodeBase64URLSafeString(imageData);
BufferedImage image = Base64StringToImageUtil.generateImageFromString(qrCodeBase64);
qrCodeOriginUrlExtracted = QrCodeDecoderUtil.decodeQrCode(image);
imageInFile.close();
}
catch (Exception e)
{
// TODO: handle exception
}
System.out.println(String.format("Extracted text from qr code: %1$s", qrCodeOriginUrlExtracted));
}
Errors generated:
Exception in thread "main" {"errorCode": "3000", "debugInfo":"null","message": "com.google.zxing.NotFoundException"}
at com.waijule.common.util.image.QrCodeDecoderUtil.decodeQrCode(QrCodeDecoderUtil.java:44)
at com.waijule.common.util.image.QrCodeDecoderUtil.main(QrCodeDecoderUtil.java:58)
Caused by: com.google.zxing.NotFoundException
The template qr code provided as following:
Thanks for all the little helps.
On the whole, the decode method depends on the specific circumstance, DecodeHintType and barcode reader need to specify in advance. Refer to the open source of https://zxing.org/w/decode.jspx from zxing, pay attention to the method 'processImage'.
Thanks for the followers these days.
Related
Generally, I am using below code to take a screenshot and attach in allure report :
#Attachment(value = "Page Screenshot", type = "image/png")
public static byte[] saveScreenshotPNG(WebDriver driver) {
return ((TakesScreenshot)driver).getScreenshotAs(OutputType.BYTES);
}
But now my need is I have already some screenshot on my desktop and want to attach it with an allure report. is that possible?
You can take the existing image and convert it to byte[]. getScreenshotAs() decodes the screenshot string so you might need to do it as well
Java
#Attachment(value = "Page Screenshot", type = "image/png")
public static byte[] saveScreenshotPNG(String path) {
File file = new File(path);
BufferedImage bufferedImage = ImageIO.read(file);
byte[] image = null;
try (ByteArrayOutputStream bos = new ByteArrayOutputStream()) {
ImageIO.write(bufferedImage, "png", bos);
image = bos.toByteArray();
} catch (Exception e) { }
// if decoding is not necessary just return image
return image != null ? Base64.getMimeDecoder().decode(image) : null;
}
Python
with open(path, 'rb') as image:
file = image.read()
byte_array = bytearray(file)
allure.attach(byte_array, name="Screenshot", attachment_type=AttachmentType.PNG)
So, I am downloading the profile picture from the Google SIgn-in api and I save it to a hidden file. The problem is that when I try to retrieve it, it throws me: D/skia: --- Failed to create image decoder with message 'unimplemented'. However when I retrieve an image from FireBaseStorage and save that one to the hidden file I can retrieve it whithout any problems.
I tried BitmapFactory.decodeByteArray(), but then I had a message telling me skia wasn't able to decode the file and it returned null.
The method I use to retrieve the profile picture and call the method that will save the file
private void getUsersPic() {
Bitmap profilePic;
try {
InputStream in = new URL(AppData.getUser().getPicture()).openConnection().getInputStream();
profilePic = BitmapFactory.decodeStream(in);
int size = profilePic.getRowBytes()*profilePic.getHeight();
ByteBuffer b = ByteBuffer.allocate(size);
byte[] bytes = new byte[size];
profilePic.copyPixelsToBuffer(b);
b.position(0);
b.get(bytes, 0, bytes.length);
SaveBitmapToFile.saveBitmap(bytes , AppData.getUser().getName()+AppData.getUser().getLastName());
} catch(Exception e) {
System.out.println("Get profile pic: "+e.toString());
}
}
Save the file
public static void saveBitmap(byte[] bitmap, String key) {
String path = AppData.getAppContext().getFilesDir()+"/.image"+"/";
File fileDir = new File(path);
if(!fileDir.isDirectory())
fileDir.mkdirs();
try {
File bitmapDir = new File(fileDir+"/"+key);
bitmapDir.createNewFile();
FileOutputStream stream = new FileOutputStream(bitmapDir);
stream.write(bitmap);
stream.close();
} catch (IOException e) {
System.out.println("Problem creating file "+e.toString()+ " Directory: "+fileDir);
}
}
Retrieve and return a bitmap
public static Bitmap getBitmap(String key) {
File file = new File(AppData.getAppContext().getFilesDir()+"/.image/"+key);
try {
BufferedInputStream buf = new BufferedInputStream(new FileInputStream(file));
return BitmapFactory.decodeStream(buf);//BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
} catch(Exception e) {
System.out.println("Exception getting bitmap: "+e.toString());
return null;
}
}
The last method should return a Bitmap and it is doing it. It is just not working when the image comes from the Google Sign-in api.
As pskink said in the comment of the post, I had to use compress() instead of copyPixelToBuffer(). Here is my updated method:
private void getUsersPic() {
Bitmap profilePic;
try {
InputStream in = new URL(AppData.getUser().getPicture()).openConnection().getInputStream();
profilePic = BitmapFactory.decodeStream(in);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
profilePic.compress(Bitmap.CompressFormat.PNG, 100, stream);
SaveBitmapToFile.saveBitmap(stream.toByteArray() , AppData.getUser().getName()+AppData.getUser().getLastName());
} catch(Exception e) {
System.out.println("Get profile pic: "+e.toString());
}
}
Anybody have any idea about,How to handle unstructured data like Audio,Video and Images using Hbase.I tried for this alot but i didn't get any idea.please any help is appreciated.
Option 1: convert image to byte array and you can prepare put request and insert to table. Similarly audio and video files also can be achieved.
See https://docs.oracle.com/javase/7/docs/api/javax/imageio/package-summary.html
import javax.imageio.ImageIO;
/* * Convert an image to a byte array
*/
private byte[] convertImageToByteArray (String ImageName)throws IOException {
byte[] imageInByte;
BufferedImage originalImage = ImageIO.read(new File(ImageName));
// convert BufferedImage to byte array
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(originalImage, "jpg", baos);
imageInByte = baos.toByteArray();
baos.close();
return imageInByte;
}
Option 2 : You can do that in below way using Apache commons lang API. probably this is best option than above which will be applicable to all objects including image/audio/video etc.. This can be used NOT ONLY for hbase you can save it in hdfs as well
See my answer for more details.
For ex : byte[] mediaInBytes = org.apache.commons.lang.SerializationUtils.serialize(Serializable obj)
for deserializing, you can do this static Object deserialize(byte[] objectData)
see the doc in above link..
Example usage of the SerializationUtils
import java.io.FileInputStream;
import java.io.FileOutputStream;
import org.apache.commons.lang.SerializationUtils;
public class SerializationUtilsTest {
public static void main(String[] args) {
try {
// File to serialize object to it can be your image or any media file
String fileName = "testSerialization.ser";
// New file output stream for the file
FileOutputStream fos = new FileOutputStream(fileName);
// Serialize String
SerializationUtils.serialize("SERIALIZE THIS", fos);
fos.close();
// Open FileInputStream to the file
FileInputStream fis = new FileInputStream(fileName);
// Deserialize and cast into String
String ser = (String) SerializationUtils.deserialize(fis);
System.out.println(ser);
fis.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
Note :jar of apache commons lang always available in hadoop cluster.(not external dependency)
I generated a QRCode using zxing library.
QRCode qrcode = QRCode.from("Encoding string").withSize(17,17).to(ImageType.PNG);
ByteArrayOutputStream out = QRCode.from(output.toString()).withSize(10, 10).to(ImageType.PNG).stream();
FileOutputStream fout = new FileOutputStream(new File("D:\\QR_Code.JPG"));
fout.write(out.toByteArray());
fout.flush();
fout.close();
It works fine but now I want to decode generated QRCode. Is it possible to decode QRCode from an image with zxing? If so, can you give me a hint how to do it because I haven't found appropriate class or method. Thanks in advance.
Here is what you can do:
You'll need an instance of QRCodeReader to decode qrcode data from a BinaryBitmap
You need to instanciate a HybridBinarizer and pass it as a constructor argument to create your BinaryBitmap
The HybridBinarizer needs an instance of LuminanceSource
Take a look at BufferedImageLuminanceSource
Here is an example that would decode data from a buffered image:
public static String qrDecodeFromImage(BufferedImage img) {
if(img!=null) {
LuminanceSource bfImgLuminanceSource = new BufferedImageLuminanceSource(img);
BinaryBitmap binaryBmp = new BinaryBitmap(new HybridBinarizer(bfImgLuminanceSource));
QRCodeReader qrReader = new QRCodeReader();
Result result;
try {
result = qrReader.decode(binaryBmp);
return result.getText();
} catch (NotFoundException e) {} catch (ChecksumException e) {} catch (FormatException e) {}
}
return null;
}
You'll need to have the ZXing project included in your project(source, etc).
Then you can use all sorts of ZXing classes to performing decoding/encoding, etc:
Look into these classes: BinaryBitmap, QRCodeReader, ParsedResult, ResultParser and give this a try:
Bitmap b = ...;//TODO: create a bitmap from your source...
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(new RGBLuminanceSource(b)));
Result result = null;
QRCodeReader reader = new QRCodeReader();
try {
result = reader.decode(bitmap);
ParsedResult parsedResult = ResultParser.parseResult(result);
//TODO: use parsedResult
}
catch(OutOfMemoryError e) {
}
catch(Exception e) {
}
I need to send pictures from raspberry pi (written in python) to server (in java). I have read that the easiest way is to encode image to base64 send it and decode on the server side.
Now I have a generated base64 txt file from png.
I need a program to decode it.
I have folder in which I have my base64 code(64kb in one line of txt file)
encoding program that looks like
import urllib
encoded = urllib.quote(open("/home/wojtek/Desktop/wideo/nazdjecia/test_image1.png", "rb").read().encode("base64"))
print encoded
f = open("path/obr.txt",'w')
f.write(encoded)
f.close()
print "done"
and program that looks like this
public class JavaApplication2 {
public static BufferedImage decodeToImage(String imageString)
{
BufferedImage image = null;
byte[] imageByte;
try
{
BASE64Decoder decoder = new BASE64Decoder();
imageByte = decoder.decodeBuffer(imageString);
ByteArrayInputStream bis = new ByteArrayInputStream(imageByte);
image = ImageIO.read(bis);
bis.close();
}
catch (Exception e)
{
e.printStackTrace();
}
return image;
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
try {
BufferedReader in = new BufferedReader(new FileReader("/filepath/obr.txt"));
String str;
str = in.readLine();
NewJFrame gui = new NewJFrame();
gui.setVisible(true);
BufferedImage im = decodeToImage(str);
ImageIcon ico = new ImageIcon(im);
gui.imgset(ico );
// str is one line of text; readLine() strips the newline character(s)
in.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
when I try to decode it with java it crashes
Picked up JAVA_TOOL_OPTIONS: -javaagent:/usr/share/java/jayatanaag.jar
javax.imageio.IIOException: Error skipping PNG metadata at
com.sun.imageio.plugins.png.PNGImageReader.readMetadata(PNGImageReader.java:680)
at
com.sun.imageio.plugins.png.PNGImageReader.readImage(PNGImageReader.java:1229)
at
com.sun.imageio.plugins.png.PNGImageReader.read(PNGImageReader.java:1577)
at javax.imageio.ImageIO.read(ImageIO.java:1448) at
javax.imageio.ImageIO.read(ImageIO.java:1352) at
javaapplication2.JavaApplication2.decodeToImage(JavaApplication2.java:33)
at javaapplication2.JavaApplication2.main(JavaApplication2.java:55)
Caused by: java.io.EOFException at
javax.imageio.stream.ImageInputStreamImpl.readInt(ImageInputStreamImpl.java:251)
at
com.sun.imageio.plugins.png.PNGImageReader.readMetadata(PNGImageReader.java:666)
... 6 more java.lang.NullPointerException at
javax.swing.ImageIcon.(ImageIcon.java:228) at
javaapplication2.JavaApplication2.main(JavaApplication2.java:56)
what am I doing wrong... :(