Hi I have a byte array that I am converting to jpg image but that is giving exception as below please explain me wht is the problem with this.
ByteArrayInputStream bis = new ByteArrayInputStream(someByteArray);
Iterator<?> readers = ImageIO.getImageReadersByFormatName("jpg");
//ImageIO is a class containing static methods for locating ImageReaders
//and ImageWriters, and performing simple encoding and decoding.
ImageReader reader = (ImageReader) readers.next();
Object source = bis;
ImageInputStream iis = ImageIO.createImageInputStream(source);
reader.setInput(iis, true);
ImageReadParam param = reader.getDefaultReadParam();
BufferedImage image = reader.read(0, param);
//got an image file
BufferedImage bufferedImage = new BufferedImage(image.getWidth(null), image.getHeight(null), BufferedImage.TYPE_INT_RGB);
//bufferedImage is the RenderedImage to be written
Graphics2D g2 = bufferedImage.createGraphics();
g2.drawImage(image, null, null);
File imageFile = new File("D:\\newrose2.jpg");
ImageIO.write(bufferedImage, "jpg", imageFile);
Exception:
javax.imageio.IIOException: Invalid JPEG file structure: SOS before SOF
at com.sun.imageio.plugins.jpeg.JPEGImageReader.readImageHeader(Native Method)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.readNativeHeader(JPEGImageReader.java:550)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.readNativeHeader(JPEGImageReader.java:550)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.checkTablesOnly(JPEGImageReader.java:295)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.gotoImage(JPEGImageReader.java:427)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.readHeader(JPEGImageReader.java:543)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.readInternal(JPEGImageReader.java:986)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.read(JPEGImageReader.java:966)
at Trnsport.writejpegfile(Trnsport.java:398)
at Trnsport.getData(Trnsport.java:107)
at Trnsport.run(Trnsport.java:63)
at java.lang.Thread.run(Thread.java:722)
Edit:
FileOutputStream fos = new FileOutputStream("image" + new Date().getTime() + ".jpg");
fos.write(someByteArray);
fos.close();
If your byte array already contains valid JPEG data, you do not need to invoke the JPEG reader or writer -- you can write the bytes to the file using ordinary file I/O.
If the byte array actually contains some format of raw pixel data, you will need to load it into a BufferedImage directly (such as via setRGB) and encode that as a JPEG.
The fact that you're getting an exception trying to decode it implies it is not JPEG data, but raw pixel data. Or, perhaps it is a different type of image altogether, or it has an image at some offset into the array instead of at the start the array, or it is not an image at all.
Related
I have a ReadableByteChannel which contains an image (either obtained from an URL or a file). I write the Channel finally into a File with a code like
final FileOutputStream fileOutputStream = new FileOutputStream(outImageName);
fileOutputStream.getChannel().transferFrom(imageByteChannel, 0, Long.MAX_VALUE);
fileOutputStream.close();
Since it is unclear if the image is a png or a jpeg or ... I want to make sure and save it as png. I know I can use the ImageIO.write(buffImg, outImageName, "png");
But somehow this requires that the buffImg is a RenderedImage which raises the question how to obtain it?
Is there a simpler solution than reading the file from the file system with ImageIO and than write it as png? Can I convert it directly within the memory?
Plus an additional question: Is there a way to tell ImageIO to get rid of the AlphaChannel (=transparent)?
If you can, I suggest getting the InputStream or the underlying File or URL objects instead of a ReadableByteChannel, as ImageIO.read(..) supports all those types as input directly.
If not possible, you can use Channels.newInputStream(..) to get an InputStream from the byte channel, to pass on to ImageIO.read(...). There's no need to write to a file first.
Code:
ReadableByteChannel channel = ...; // You already have this
BufferedImage image = ImageIO.read(Channels.newInputStream(channel))
To get rid of any unwanted transparency, you could do:
BufferedImage opaque = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_3BYTE_BGR);
Graphics2D g = opaque.createGraphics();
try {
g.setColor(Color.WHITE); // Or any other bg color you like
g.fillRect(0, 0, image.getWidth(), image.getHeight());
g.drawImage(image, 0, 0, null);
}
finally {
g.dispose();
}
You can now write the image in PNG format, either to a file or stream:
if (!ImageIO.write(opaque, "PNG", new File(outputFile)) {
// TODO: Handle odd case where the image could not be written
}
I need a dynamic solution to convert a unknown image format to .png in java.
Will .getType() help me out here, it seems only to return numbers.
The converted image should later be stored in a folder, but I guess that is easly done in the
ImageIO.write().
It's just that with converting an unknown image format that I have no idea how to approach.
This peace of code should do the magic:
File file = new File("unknown.type.pic");
ByteArrayInputStream bais = new ByteArrayInputStream(FileUtils.readFileToByteArray(file);
BufferedImage image = ImageIO.read(bais);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(image, "jpg", baos);
OutputStream outputStream = new FileOutputStream ("output.jpg");
baos.writeTo(outputStream);
Add missing try/catch/finally blocks.
I am trying to convert Image to Byte Array and save it in database. Image to Byte Conversion and bytes to Image Conversion using ImageIO Method works completely fine before saving it into database. But when i retrieve bytes from Database ImageIO returns null.
FileInputStream fis = new FileInputStream(picturePath);
BufferedImage image = ImageIO.read(new File(picturePath));
BufferedImage img = Scalr.resize(image, Scalr.Mode.FIT_EXACT, 124, 133, Scalr.OP_ANTIALIAS);
ByteArrayOutputStream ByteStream = new ByteArrayOutputStream();
ImageIO.write(img, "jpg", ByteStream);
ByteStream.flush();
byte[] imageBytes = ByteStream.toByteArray();
ByteStream.close();
PersonImage = imageBytes;
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(PersonImage);
BufferedImage ImageForBox = ImageIO.read((InputStream)byteArrayInputStream);
PersonImageBox.setIcon(new ImageIcon((Image)ImageForBox));
Above code is what I do before saving picture bytes in DB. I resize the Image then convert it into bytes and then convert other way around and show it in JLabel, it works fine. But when I retrieve bytes from database and use the same code i.e.
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(PersonImage); // PersonImage are bytes from dB.
BufferedImage ImageForBox = ImageIO.read((InputStream)byteArrayInputStream);
PersonImageBox.setIcon(new ImageIcon((Image)ImageForBox));
In this case ImageIO returns null. Please help.
I have array[Byte] of file, saved on DB.
Is there a way to convert it to JPG if its for example PNG ?
And no saving file on disc, just operations on those array[byte]
Thanks!
Read it into a BufferedImage and write it again to a byte array, using JPG encoding.
InputStream is = ...;
BufferedImage img = ImageIO.read(is);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(img, "JPG", baos);
byte[] array = baos.toByteArray();
For the inputstream (is), use either a inputstream that comes straight from the BLOB in your DB, or use a ByteArrayInputStream.
I see that a number of people have had a similar problem, however I'm yet to try find exactly what I'm looking for.
So, I have a method which reads an input image and converts it to a byte array:
File imgPath = new File(ImageName);
BufferedImage bufferedImage = ImageIO.read(imgPath);
WritableRaster raster = bufferedImage .getRaster();
DataBufferByte data = (DataBufferByte) raster.getDataBuffer();
What I now want to do is convert it back into a BufferedImage (I have an application for which I need this functionality). Note that "test" is the byte array.
BufferedImage img = ImageIO.read(new ByteArrayInputStream(test));
File outputfile = new File("src/image.jpg");
ImageIO.write(img,"jpg",outputfile);
However, this returns the following exception:
Exception in thread "main" java.lang.IllegalArgumentException: im == null!
This is because the BufferedImage img is null. I think this has something to do with the fact that in my original conversion from BufferedImage to byte array, information is changed/lost so that the data can no longer be recognised as a jpg.
Does anyone have any suggestions on how to solve this? Would be greatly appreciated.
This is recommended to convert to a byte array
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(img, "jpg", baos);
byte[] bytes = baos.toByteArray();
Note that calling close or flush will do nothing, you can see this for yourself by looking at their source/doc:
Closing a ByteArrayOutputStream has no effect.
The flush method of OutputStream does nothing.
Thus use something like this:
ByteArrayOutputStream baos = new ByteArrayOutputStream(THINK_ABOUT_SIZE_HINT);
boolean foundWriter = ImageIO.write(bufferedImage, "jpg", baos);
assert foundWriter; // Not sure about this... with jpg it may work but other formats ?
byte[] bytes = baos.toByteArray();
Here are a few links concerning the size hint:
Java: Memory efficient ByteArrayOutputStream
jpg bits per pixel
Of course always read the source code and docs of the version you are using, do not rely blindly on SO answers.