Created
April 10, 2016 16:39
-
-
Save jeffThompson/ea54b5ea40482ec896d1e6f9f266c731 to your computer and use it in GitHub Desktop.
A Processing sketch to save JPG images with variable compression
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
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(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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/).