Although a bit late (since the question has already been answered), and because, coincidentally, I have been working with ImageIO over the past few days, I will simply add my answer here. Especially the second part of how to make JpegImagesToMovie to work with png files has not received an answer, and this may help someone else.
Double Compression Problem:. As correctly identified by others, you effectively compress a JPEG image twice using ImageIO.write() . ImageIO is a utility class based on the file type ("jpeg" in our case) selects the appropriate ImageWriter . Then it creates an ImageInputStream and passes it to the author. In the latter case, it calls its write() method. Pretty much what @meewoK does in its answer. However, each ImageWriter can accept an instance of ImageWriteParam that adjusts its details. ImageIO , apparently, cannot know what parameters each author can take and how it should be configured, so the default settings are used. If you look at the source, JPEGImageWriteParam has a default quality factor of 0.75 , so you effectively multiply this coefficient by any quality used for the source file. (If it was 0.75 again, your final image is pretty much 0.75 * 0.75 = 0.56 , meaning you lost half of the original). Bottom line: use ImageIO for quick reading or writing, but if you need more control, it is recommended that you use ImageWriter manually.
How to make JpegImagesToMovie work directly with PNG files:. If you look at the source of this class, all the work is done in its inner class ImageSourceStream . What he does is that he loads bytes from files (each file is a video frame) directly into the Processor class that creates the video. Conveniently, Processor knows how to handle the JPEG format directly (look at the stream constructor format = new VideoFormat(VideoFormat.JPEG, ...) ), so loading it with raw file data works as expected.
To make it work with the PNG format, simply replacing the file suffix according to your approach is not enough. You need to convert the PNG data to a format that Processor understands (that is, to decode it). Below you can find a quick and dirty way to do this. Disclaimer:. The approach below uses more memory, as it loads the image into memory and then processes it to convert it to byte[] . So the worst in performance and memory. However, if memory and speed are not a problem, this will allow you to work directly with PNG files.
Conversion Steps:
a) . When searching for an editor and replacing the string values "jpeg", "jpg" with "png" . The original author has these hardcoded values, and during your attempt you missed some entries.
b) In the ImageDataSource constructor ImageDataSource replace the first line with the second:
streams[0] = new ImageSourceStream(width, height, frameRate, images); // delete this line streams[0] = new PngImageSourceStream(width, height, frameRate, images); // add this line
c) At the end of the class, add the implementation of the new PngImageSourceStream below.
Now you should have a working copy of the original version, which can directly read PNG files and convert them to MOV video (Note. Not all players can play this new video because of the codec used. QuickTime and Media Player Classic worked fine for me)
Update 1: PngImageSourceStream source code assumes a 32-bit PNG file, a limitation that I forgot to mention. The next version is the second version, which supports 32-bit or 24-bit (that is, no alpha layer) images.
class PngImageSourceStream extends ImageSourceStream { public PngImageSourceStream(int width, int height, int frameRate, Vector<String> images) { super(width, height, frameRate, images);