I have a collection of buffered images that I want to serialize and then deserialize.
For example I have an arrayList full of buffered images which are iterated through and written to a
ObjectOutputStream
for (BufferedImages i : images{
ImageIO.write(i,"png",ImageIO.createImageOutputStream(output));
}
When I go to re-serialize the images, I tried to use
BufferedImage image =ImageIO.read(ImageIO.createImageInputStream(input));
but it only reads in one image.
Whats the correct way to re-serialize a collection of buffered images stored within the same serialized file?
Also once the images have been re-serialized they get redrawn to a JLabel,
How do I know which image is the correct one for each JLabel?
Edit:Problem solved
Ended up converting the buffered images to a byte array then stuck them in a hash map and used some hash codes as keys.
Then serialized the hash map.
All good.
Related
When I use the robot class to get multiple screenshots of my screen, then convert the bufferedimage to a byte array, the lengths of the byte arrays vary, sometimes by a lot. Should this be happening? I feel as though the amount of bytes in each picture would be the same.
For background I am trying to speed up a simple screen sharing program. Right now I am sending each picture as a complete byte array which works fine (but is slow). I would like to keep every picture in a buffer, then send only the changes and indexes in the byte arrays of the changes from the last picture to the next, cutting down on data sent over the socket. This isn’t working out as each screenshot has a different sized byte array.
Your screenshots are different sizes because they've got different amounts of complexity.
You haven't included a lot of detail in your question, so I'm going to assume that the screenshot routine you're using returns a PNG image.
The PNG format isn't just an array of (red, green, blue) data with one entry for every pixel of your image. Instead, the format compresses the image data. This means that (for example) an image that was just a single flat colour would be much smaller than one where every pixel was a different colour.
I am working a project involves visualizing a star catalog and create a printable bmp file. If I want to print a 24 by 24 picture with 1200 dpi resolution, it would be 28800*28800 and roughly 2.32 Gb.
Generally when create a bmp file, one would make a BufferedImage, graph something with the setRGB method, and save it as a bmp file with ImageIO.write.
But as I try to distribute my program, the end user may not have sufficient free RAM, and it will cause an OutOfMemoryError.
Is there a way to avoid saving every pixel of the image on RAM? If I can horizontally cut the image into several bands, and save them one by one to a single bmp file, it would be great (since I can get ride of the saved buffers).
Something similar would be:
Before I find the imageIO and awt package, I wrote a Bitmap class that saves a bitmap as a csv file and use an external software to render it. It has a toString method, and I use the method to save the content of the csv as a string instead of actually save it on the disk. When I want to make a large image, I create a fileWriter and a printWriter. I buffer a horizontal band of the image, and write it to the disk with the printWriter. Then I buffer the next band and replace the old band, and write it with the printWriter again. When it is finished, I close the writers and have the complete bitmap as a csv file on my disk.
What you need is code that directly creates an image file without loading the data completely into memory (usually this is called tiled image processing). I don't know a Java library that allows to do so, therefore my recommendation would be to look at the BMP file format and just write the file manually. AFAIR the BMP file format is pretty simple.
Some time ago I have seen something similar for PNG output: PngXxlWriter.java
I would like to read an image and then change its format but without saving it.
For example I can read the image like this
BufferedImage img=ImageIO.read(new File(fileName));
Then I want to change the format of img, for example from jpeg to png.
The only way I found is to use ImageIO.read to write and then read the new image, but it does seem to be an efficient way to do it.
When you "read" the image via
BufferedImage img=ImageIO.read(new File('myimage.png'));
you are not only reading but also decoding it, i.e., transforming the raw bytes in the (say) PNG format to some "RAW" format that your aplication or API can manipulate (or display) - in this case, a BufferedImage. Once this is done, the fact that this image came from a PNG file is forgotten. To read it as PNG and save it as JPEG you need to decode it (as PNG) and then code it (as JPG).
I would like to read an image and then change its format but without saving it.
The "format" of the image (in the PNG/JPEG sense) gives you a way of packing an image in a sequence of bits. So, your desire makes little sense. At most, you could store those bits in memory (what for?), but that would be the same as "saving it" (to memory instead of disk).
What are the advantages of converting a buffered image into an array of integers?I assume that i can manipulate the array and cross process the picture .Is that so?
I think you are referring to getRgb() method of BufferedImage class.
Supposing you want to modify the whole image or a big portion of it, retrieving the pixel array, and perform operations on it could be considerely faster than accessing each single pixel through method calls such as setRgb().
SwingX introduces the AbstractFilter class for BufferedImage. Here is an example:
http://www.jarvana.com/jarvana/view/org/swinglabs/swingx/0.9/swingx-0.9-sources.jar!/org/jdesktop/swingx/image/GaussianBlurFilter.java?format=ok
For simple editing use one of this examples:
http://www.exampledepot.com/egs/java.awt.image/imagepixel.html
Buffered image pixel manipulation
How do I create a BufferedImage from array containing pixels?
Having a BufferedImage into memory as an array of int values could help you apply filters on the image by processing the int values into memory and then setting the result back to another BufferedImage.
I am generating lots of images in java and saving them through the ImageIO.write method like this:
final BufferedImage img = createSomeImage();
ImageIO.write( img, "png", new File( "/some/file.png" );
I was happy with the results until Google's firefox addon 'Page Speed' told me that i can save up to 60% of the size if i optimize the images. The images are QR codes, their size is around 900B each and the firefox-plugin optimized versions are around 300B.
I'd like to save such optimized 300B Images directly from java.
So here my question again: How to save optimized png images with java's ImageIO?
Use PngEncoderB to convert your BufferedImage into a PNG encoded byte array.
You can apply a filter to it, which helps prepare the image for better optimization. This is what OptiPNG does, only OptiPNG calculates which filter will get you the best compression.
You might have to try applying each filter to see which one is consistently better for you. With 2 bit color, I think the only filter that might help is "up", so I'm guessing that's the one to use.
Once you get the image to a PNG encoded byte array, you can write that directly to a file.