Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
A Processing sketch to save JPG images with variable compression
/*
JPEG COMPRESSION
Jeff Thompson | 2016 | www.jeffreythompson.org
For web-based images, controlling the compression of a JPG
can optimize dimensions and file size. The built-in save()
command for Processing doesn't give us this control, but we
can use Java's ImageIO to add this functionality.
*/
import java.awt.image.BufferedImage;
import javax.imageio.plugins.jpeg.*;
import javax.imageio.*;
import javax.imageio.stream.*;
void setup() {
// set the amount of compression
// 1.0 = no compression, largest image file
// 0.5 = 50% compression
// 0.0 = 100% compression, smallest image file
float compressionLevel = 0.5;
// image to compress and image to output
String imageFile = sketchPath("") + "test.jpg";
String outputFilename = sketchPath("") + "compressed.jpg";
try {
// setup JPG output
JPEGImageWriteParam jpegParams = new JPEGImageWriteParam(null);
jpegParams.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
jpegParams.setCompressionQuality(compressionLevel);
final ImageWriter writer = ImageIO.getImageWritersByFormatName("jpg").next();
writer.setOutput(new FileImageOutputStream(new File(outputFilename)));
// load image to compress
// alternatively, you could access the sketch's pixel array and save it
PImage img = loadImage(imageFile);
img.loadPixels();
// output to BufferedImage object
// create the object, then write the pixel data to it
BufferedImage out = new BufferedImage(img.width, img.height, BufferedImage.TYPE_INT_RGB);
for (int i=0; i<img.pixels.length; i++) {
out.setRGB(i%img.width, i/img.width, img.pixels[i]);
}
// save it!
writer.write(null, new IIOImage(out, null, null), jpegParams);
println("Saved!");
}
catch (Exception e) {
println("Problem saving... :(");
println(e);
}
// all done
exit();
}
@kasperkamperman

This comment has been minimized.

Copy link

@kasperkamperman kasperkamperman commented Feb 12, 2018

Thanks for sharing this code. I've utilised it in an example that shows how to upload images with Processing to a webserver. See: https://www.kasperkamperman.com/blog/processing-save-image-to-web/

I've modified the loadImage part to get rid of the for-loop, that walks through all the pixels. I suppose the solution below could be faster (although I didn't test it).

Instead of the code from line 41 - 49 I've used:
BufferedImage in = (BufferedImage) img.getNative();
BufferedImage out = new BufferedImage(img.width, img.height, BufferedImage.TYPE_INT_RGB);
out.getGraphics().drawImage(in,0,0,null);

(based on this resource: https://blog.idrsolutions.com/2009/10/converting-java-bufferedimage-between-colorspaces/).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.