Decoding QRCode with zxing. Java - java

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) {
}

Related

How to attach custom/existing screenshot in allure report?

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)

Save image to internal storage

I want to save some images in internal storage. Here is my code:
Bitmap bitmap = ((BitmapDrawable)iv_add.getDrawable()).getBitmap();
File file = getApplicationContext().getDir("Images",MODE_PRIVATE);
file = new File(file, "UniqueFileName"+".jpg");
try{
OutputStream stream = null;
stream = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.JPEG,100,stream);
stream.flush();
stream.close();
}catch (IOException e)
{
e.printStackTrace();
}
As I understood, the picture needs to go into internal_storage/android/data/project_name/file. When I choose a picture from my gallery and click the button to save it, nothing happens and the program starts lagging. What can I do?
This line is your problem.
ContextWrapper wrapper = new ContextWrapper(getApplicationContext());
You are not supposed to create the context wrapper yourself.
File file = getApplicationContext().getDir("Images",MODE_PRIVATE);
file = new File(file, "UniqueFileName"+".jpg");
try{
OutputStream stream = null;
stream = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.JPEG,100,stream);
stream.flush();
stream.close();
}catch (IOException e)
{
e.printStackTrace();
}

How to clone an Object by copy ByteArrayOutputStream into ByteArray, then call it by ByteArrayInputStream?

I try to clone an Object by 1) shoving it into a ByteArrayOutputStream 2) assigning the stream to a byte array 3) reading the byte array by ByteArrayInputStream. However, this won't work as I can not assign the OutputStream to the byte array, the line will just not execute.
Apporoach is based Java Serializable Object to Byte Array
public Bank clone() {
Bank objektKopie = null;
byte[] byteKopie = null;
ByteArrayOutputStream bo = new ByteArrayOutputStream();
ObjectOutputStream oo = null;
try {
bo = new ByteArrayOutputStream();
oo = new ObjectOutputStream(bo);
oo.writeObject(this);
oo.flush() ;
byteKopie = bo.toByteArray(); // THIS WILL NOT HAPPEN
} catch (Exception e) {
System.out.println(e.getMessage());
} finally {
try {
bo.close();
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
ByteArrayInputStream bi = new ByteArrayInputStream(byteKopie); // byteKopie IS STILL NULL
ObjectInputStream oi = null;
try {
oi = new ObjectInputStream(bi);
objektKopie = (Bank) oi.readObject();
} catch (Exception e) { System.out.println(e.getMessage()); }
return objektKopie;
}
Your code is throwing "NotSerializable" exception, your class Bank NEEDS to implement Serializable
if dependencies are okay, GSON can do this fairly easily

Skia error when trying to retrieve a bitmap downloaded from Google Sign-in

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());
}
}

com.google.zxing.NotFoundException while using zxing to decode qrcode

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.

Categories