Convert QRCode to Image. Java - java

Using the following libraries:
qrgen-1.2, zxing-core-1.7, and
zxing-j2se-1.7 I generated QRCode:
ByteArrayOutputStream out = QRCode.from(output.toString()).withSize(1000,1000).to(ImageType.PNG).stream();
FileOutputStream fout = new FileOutputStream(new File("D:\\QR_Code.JPG"));
fout.write(out.toByteArray());
fout.flush();
fout.close();
What I intend to do with it, is to send code to a method that accepts java.awt.Image.
How can I convert an instance of QRCode class into an instance of Image class without creating QRCode.JPG at the first place? As I see, this library doesn't provide users with methods that can carry this out, so is it possible at all? May be I can convert stream to Image?

Simply write the qr code to a byte array output stream then use byte array in the stream to create a BufferedImage.
import net.glxn.qrgen.QRCode;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
public static BufferedImage generate() {
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
QRCode.from("http://www.stackoverflow.com").writeTo(baos);
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
return ImageIO.read(bais);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}

Related

Want to compress jpeg using blob with image as in and out parameter

i want to compress a jpeg Image, running a java program from an pl/sql procedure within th oracle database.
I want to call the java class from pl/sql procedure with the blob (jpeg image), an the java program should return the compresses image in a blob.
I have found this code from https://examples.javacodegeeks.com/desktop-java/imageio/compress-a-jpeg-file/ an it works fine and the jpeg images are compressed. But this program used jpeg-Files in the file system, i need the original image and the compresse image as blob parameter
I have used this program and have modified it to do what I need it to do.
To test my program, I get a jpg image from my database as blob via odbc an then call compressJPEG (myBlobCopy) with the blob. To show what happend, i do some output in the classes. The size of the blob before an after calling the compressJPEG is the same.
Here the output:
126 23190 myimage.jpg Length of retrieved Blob: 4284416
Length of copy Blob: 4284416
Call compressJPEG (myBlobCopy)
now in compressJPEG
Back from compressJPEG: Length of retrieved Blob: 4284416
Here the class. It seems, that the compressed image (blob) is not returned. Please can you help me!!!!!!
import java.sql.*;
import javax.imageio.ImageIO;
import java.io.File;
import java.io.IOException;
import java.awt.image.BufferedImage;
import java.awt.image.RenderedImage;
import java.sql.Blob;
import java.io.OutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Iterator;
import javax.imageio.IIOImage;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageWriter;
import javax.imageio.stream.ImageOutputStream;
//import java.sql.SQLException;
class OracleConCompressBLOB{
public static void main(String args[]){
try{
//step1 load the driver class
Blob myBlob = null;
Blob myBlobCopy = null;
Class.forName("oracle.jdbc.driver.OracleDriver");
String dbURL = "jdbc:oracle:thin:#(DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = xxxx)(PORT = 1521)) (CONNECT_DATA = (SERVER = DEDICATED)(SERVICE_NAME = xxxx) ) )";
String strUserID = "xxxx";
String strPassword = "xxxxx";
//step2 create the connection object
Connection con=DriverManager.getConnection(dbURL,strUserID,strPassword);
//step3 create the statement object
Statement stmt=con.createStatement();
//step4 execute query
// fuer pbent ResultSet rs=stmt.executeQuery("select PRFO_ID, PRFO_PRAX_ID , PRFO_DATEINAME, PRFO_FOTO from T_PRAFOTO where PRFO_ID = 17");
ResultSet rs=stmt.executeQuery("select PRFO_ID, PRFO_PRAX_ID , PRFO_DATEINAME, PRFO_FOTO from T_PRAFOTO where PRFO_ID = 166 FOR UPDATE");
if (rs.next()) {
myBlob = rs.getBlob(4);
myBlobCopy = myBlob;
System.out.println(rs.getInt(1)+" "+rs.getInt(2)+" "+rs.getString(3)+" Length of retrieved Blob: " + myBlob.length());
System.out.println(" Length of copy Blob: " + myBlobCopy.length());
System.out.println("Call compressJPEG (myBlobCopy) ");
compressJPEG (myBlobCopy) ;
System.out.println("back from compressJPEG: Length of retrieved Blob: " + myBlobCopy.length());
}
//step5 close the connection object
con.close();
}catch(Exception e){ System.out.println(e);}
}
public static void compressJPEG(Blob blob) throws IOException {
// File imageFile = new File("myimage.jpg");
// File compressedImageFile = new File("myimage_compressed.jpg");
// InputStream is = new FileInputStream(imageFile);
// OutputStream os = new FileOutputStream(compressed ImageFile);
System.out.println("now in compressJPEG");
BufferedImage bufferedImage = null;
OutputStream outputStream = null;
float quality = 0.5f;
try {
// create a BufferedImage as the result of decoding the supplied InputStream
// BufferedImage image = ImageIO.read(is);
bufferedImage = ImageIO.read(blob.getBinaryStream());
outputStream = blob.setBinaryStream(0);
// test
// get all image writers for JPG format
Iterator<ImageWriter> writers = ImageIO.getImageWritersByFormatName("jpg");
if (!writers.hasNext())
throw new IllegalStateException("No writers found");
ImageWriter writer = (ImageWriter) writers.next();
ImageOutputStream ios = ImageIO.createImageOutputStream(outputStream);
writer.setOutput(ios);
ImageWriteParam param = writer.getDefaultWriteParam();
// compress to a given quality
param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
param.setCompressionQuality(quality);
// appends a complete image stream containing a single image and
//associated stream and image metadata and thumbnails to the output
writer.write(null, new IIOImage(bufferedImage, null, null), param);
// close all streams
// is.close();
// os.close();
// ios.close();
// writer.dispose();
outputStream.flush();
ios.close();
outputStream.close();
writer.dispose();
} catch (IOException e) {
e.printStackTrace();
}
catch (SQLException e) {
e.printStackTrace();
}
catch(IllegalArgumentException e) {
e.printStackTrace();
}
}
}

How to add an object to file every time i run my program in java

I Have 3 objects of Person type and i write them to my file Person.person and than i read them one by one but when i run my program again i get the same 3 objets written as when i run it for the firts time.How to add those 3 objects to my file again and again every time i run my program.I want from it to be the same 3 objects or some other objects but they need to be added to the end of my file.
And how to get that data when i want to read that file?
package pisanjeUFajl;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.EOFException;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.List;
public class Serilizacija {
public static void main(String[] args) throws IOException,
ClassNotFoundException {
Person person = new Person("Jovan", "Dukic");
Person person2 = new Person("Stanko", "Maca");
Person person3 = new Person("Tole", "Lopove");
File file = new File("C:\\Users\\Jovan\\Desktop\\Person.person");
if (!(file.exists())) {
file.createNewFile();
}
ObjectOutputStream outputStream = null;
outputStream = new ObjectOutputStream(new BufferedOutputStream(new
FileOutputStream(file)));
outputStream.writeObject(person);
outputStream.reset();
outputStream.writeObject(person2);
outputStream.reset();
outputStream.writeObject(person3);
outputStream.reset();
outputStream.close();
ObjectInputStream inputStream = null;
inputStream = new ObjectInputStream(new BufferedInputStream(new
FileInputStream(file)));
int count = 0;
Person object = null;
I added more objects to my file but when i wanted to read them i got and error:
Exception in thread "main" java.io.StreamCorruptedException:
invalid typecode:AC
at java.io.ObjectInputStream.readObject0(Unknown Source)
at java.io.ObjectInputStream.readObject(Unknown Source)
at pisanjeUFajl.Serilizacija.main(Serilizacija.java:46)
It read just the first 3 objects which were added the first to my file.
try {
while (true) {
object = (Person) inputStream.readObject();
count++;
System.out.println(object);
}
} catch (EOFException error) {
System.out.println("\nEnd of file reacher - objects read = " +
count);
}
inputStream.close();
}
}
Use for writing object
ObjectOutputStream outputStream = new ObjectOutputStream(new
FileOutputStream(new File("test")));
Use it for appending object at end of file
ObjectOutputStream outputStream2 = new ObjectOutputStream(new FileOutputStream("test", true)) {
protected void writeStreamHeader() throws IOException {
reset();
}
};
for reading
ObjectInputStream inputStream = new ObjectInputStream(new FileInputStream("test"));
Use the Constructor of FileOutputStream that accepts a boolean as a parameter.
If its set to true, everything written to file through this Stream is appended to the existing content. Constructor looks like this:
FileOutputStream(File file, boolean append)

java BufferedOutputStream

package byte_base;
import java.io.FileInputStream;
import java.io.IOException;
public class FileViewer {
public static void main(String[] args) {
int a;
try{
FileInputStream fis = new FileInputStream("FileViewerln.txt");
while((a = fis.read())!=-1){
System.out.write(a);
}
}catch(IOException ioe){
System.err.println(ioe);
ioe.printStackTrace();
}
}
}
It is Program, printing text from file.
When I used FileInputStream Class and System.out.write() method, It run very well.
But I tried another way.
I used BufferedOutputStream instead of System.out.write() method.
The bottom is code using BufferedOutputStream class.
package byte_base;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
public class CopyOfFileViewer {
public static void main(String[] args) {
int a;
try{
FileInputStream fis = new FileInputStream("FileViewerln.txt");
BufferedOutputStream bos = new BufferedOutputStream(System.out);
while((a = fis.read())!=-1){
bos.write(a);
}
}catch(IOException ioe){
System.err.println(ioe);
ioe.printStackTrace();
}
}
}
But this code's result is vacuum.
I think that first code and second code is very similar.
Why did NOT it(Second Code) working well?
You forgot to close OutputStream bos.
bos.close();
Actually It's much better to do your operations in try-with-resources
try (FileInputStream fis = new FileInputStream("FileViewerln.txt");
BufferedOutputStream bos = new BufferedOutputStream(System.out);
) {
while((a = fis.read())!=-1){
bos.write(a);
}
} catch(IOException ioe){
System.err.println(ioe);
ioe.printStackTrace();
}
class InputStream implements Closeable. So its subclasses could be used in try-with-resources.
Ah the age old flush and the Buffered Stream question.
Use the flush method.
Place it after the while loop
bos.flush();
From the docs
The class implements a buffered output stream. By setting up such an
output stream, an application can write bytes to the underlying output
stream without necessarily causing a call to the underlying system for
each byte written.
The key point here is
without necessarily causing a call to the underlying system for each
byte written.
That basically means the data is buffered in memory and not written to the output stream on each write method call.
You should flush the buffer at a suitable interval and close the stream using the close method to force the final buffer out.

image file size is different after base 64 encoding/decoding

I am using the following test to read a file, base 64 encode it, then decode the base 64 back to a new image. I noticed that the new image file size (after the conversion) is significantly less than the original image leading me to think that somehow, part of the image data is being lost in the conversion. I can see the image but am worried about image quality. Any insight on what I might be doing wrong would be greatly appreciated.
Test class:
package test;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Base64;
public class ImageTest { //should be B64Test
public static void main(String[] args) {
ImageTest imageTest = new ImageTest();
try {
BufferedImage img = null;
BufferedImage finalImg = null;
try {
// img = ImageIO.read(new File("/home/user/Desktop/test1.jpg"));
img = ImageIO.read(Files.newInputStream(Paths.get("/home/user/Desktop/test1.jpg")));
//encode base64 and print
final String base64encoded = ImageConverter.encodeToString(img, "jpeg");
System.out.println("read file " + base64encoded);
//convert base64 string to image
finalImg = ImageConverter.decodeToImage(b64encoded);
ImageIO.write(finalImg, "jpeg", new File("/home/user/Desktop/test2.jpg"));
} catch (IOException e) {
System.out.println("exception " + e);
}
} catch (Exception e) {
System.out.println("exception " + e);
}
}
}
ImageConverter
package test;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.awt.image.RenderedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import sun.misc.BASE64Encoder;
import sun.misc.BASE64Decoder;
public class ImageConverter {
public static String imgToBase64String(final RenderedImage img, final String formatName) {
final ByteArrayOutputStream os = new ByteArrayOutputStream();
try {
ImageIO.write(img, formatName, Base64.getEncoder().wrap(os));
return os.toString(StandardCharsets.ISO_8859_1.name());
} catch (final IOException ioe) {
throw new UncheckedIOException(ioe);
}
}
public static BufferedImage base64StringToImg(final String base64String) {
try {
return ImageIO.read(new ByteArrayInputStream(Base64.getDecoder().decode(base64String)));
} catch (final IOException ioe) {
throw new UncheckedIOException(ioe);
}
}
public static String encodeToString(BufferedImage image, String type) {
String imageString = null;
ByteArrayOutputStream bos = new ByteArrayOutputStream();
try {
ImageIO.write(image, type, bos);
byte[] imageBytes = bos.toByteArray();
BASE64Encoder encoder = new BASE64Encoder();
imageString = encoder.encode(imageBytes);
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
return imageString;
}
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;
}
}
I can try testing both the base 64 encoder/decoder available in jdk8 as well as the one in sun.java.misc (which I realize I do not need to use). Any thoughts on what might be causing the image size to shrink (I would prefer doing that myself if needed using imagemagick or graphicsmagick etc.).
The original image was 1.2 MB (1,249,934 bytes) but the new image is 354.5 kB (354,541 bytes) - width/height is the same for both images.
As #JBNizet points out in his comment, the reason for the change in size (the size may grow as well, depending on the input image and compression settings), is that you are not just encoding/decoding binary data to/from Base64, you are also re-encoding the image data (two times) using JPEG encoding (with default encoding settings). Unless the original image was encoded with the exact same settings, you will lose some precision, and the file size will change.
Another likely reason for the decrease in file size, is that a BufferedImage does not carry any of the meta data contained in the original JPEG file. So your process of re-encoding the JPEG will also lose any Exif or XMP metadata, thumbnail, color profile etc. Depending on the source of the image, this may contribute to a significant part of the file size.
Again, as #JBNizet says, the best thing is to not involve ImageIO at all in this case, just use normal file I/O and encode the original bytes using Base64, and decode again to recover the original file contents exactly.
PS: If you intend on doing image processing on the image in between the Base64 encoding/decoding, you will of course need to decode the image data (using ImageIO or similar), but you should try to do it only once (for better performance), and perhaps look into preserving the meta data. Also, I think image encoding/decoding and Base64 encoding/decoding are separate issues, and should not be interleaved like it is now. Split it up, for a better separation of concerns.

Writing image in to a file [duplicate]

This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 7 years ago.
I am trying to write an buffered image into a file that appends the next buffered image bytes.I have the following code for which some runtime exception is thrown. when i run this code i get the following exception. Why and what has to be changed?
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import javax.imageio.ImageIO;
public class FileT
{
public static void main(String[] args)
{
try {
BufferedImage originalImage = ImageIO.read(new File("ani.jpg"));
int i=0,c=0;
// convert BufferedImage to byte array
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(originalImage, "jpg", baos);
baos.flush();
byte[] imageInByte = baos.toByteArray();
byte[] copybuf = new byte[1024];
baos.close();
while(i<imageInByte.length)
{
copybuf[c]=imageInByte[i];
c++;
if(i%1023==0)
{
// convert byte array back to BufferedImage
InputStream in = new ByteArrayInputStream(copybuf);
BufferedImage bImageFromConvert = ImageIO.read(in);
ImageIO.write(bImageFromConvert, "jpg", new FileOutputStream(new File("ani1.jpg"),true));
}
copybuf = new byte[1024];
i++;
}
}
catch (IOException e) {
System.out.println(e.getMessage());
}
}
}
Exception in thread "main" java.lang.IllegalArgumentException: image == null!
at javax.imageio.ImageTypeSpecifier.createFromRenderedImage(ImageTypeSpecifier.java:925)
at javax.imageio.ImageIO.getWriter(ImageIO.java:1592)
at javax.imageio.ImageIO.write(ImageIO.java:1578)
at FileT.main(FileT.java:45)
if(i%1023==0){
// convert byte array back to BufferedImage
InputStream in = new ByteArrayInputStream(copybuf);
BufferedImage bImageFromConvert = ImageIO.read(in);
ImageIO.write(bImageFromConvert, "jpg", new FileOutputStream(new File("ani1.jpg"),true));
}
copybuf = new byte[1024];
i++;
In this code you might want to change new FileOutputStream(new File()) to be casted to ImageOutputStream
It is very hard to determine from your question what you need, but I think this will fix it. If it doesn't just leave a comment and Ill try to fix it

Categories

Resources