mirror of
https://github.com/processing/processing4.git
synced 2026-02-14 10:55:38 +01:00
add means for setting image resolution when saving
This commit is contained in:
@@ -31,6 +31,7 @@ import java.lang.reflect.Method;
|
||||
import java.util.Iterator;
|
||||
|
||||
import javax.imageio.*;
|
||||
import javax.imageio.metadata.*;
|
||||
|
||||
|
||||
/**
|
||||
@@ -3089,8 +3090,6 @@ public class PImage implements PConstants, Cloneable {
|
||||
// JPEG and BMP images that have an alpha channel set get pretty unhappy.
|
||||
// BMP just doesn't write, and JPEG writes it as a CMYK image.
|
||||
// http://code.google.com/p/processing/issues/detail?id=415
|
||||
// String lower = path.toLowerCase();
|
||||
// if (lower.endsWith("bmp") || lower.endsWith("jpg") || lower.endsWith("jpeg")) {
|
||||
if (extension.equals("bmp") || extension.equals("jpg") || extension.equals("jpeg")) {
|
||||
outputFormat = BufferedImage.TYPE_INT_RGB;
|
||||
}
|
||||
@@ -3100,31 +3099,36 @@ public class PImage implements PConstants, Cloneable {
|
||||
|
||||
File file = new File(path);
|
||||
|
||||
ImageWriter writer = null;
|
||||
ImageWriteParam param = null;
|
||||
IIOMetadata metadata = null;
|
||||
if (extension.equals("jpg") || extension.equals("jpeg")) {
|
||||
ImageWriter writer = null;
|
||||
Iterator<ImageWriter> iter = ImageIO.getImageWritersByFormatName("jpeg");
|
||||
if (iter.hasNext()) {
|
||||
writer = iter.next();
|
||||
|
||||
if ((writer = imageioWriter("jpeg")) != null) {
|
||||
// Set JPEG quality to 90% with baseline optimization. Setting this
|
||||
// to 1 was a huge jump (about triple the size), so this seems good.
|
||||
// Oddly, a smaller file size than Photoshop at 90%, but it's a
|
||||
// completely different algorithm, I suppose.
|
||||
ImageWriteParam param = writer.getDefaultWriteParam();
|
||||
// Oddly, a smaller file size than Photoshop at 90%, but I suppose
|
||||
// it's a completely different algorithm.
|
||||
param = writer.getDefaultWriteParam();
|
||||
param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
|
||||
param.setCompressionQuality(0.9f);
|
||||
|
||||
BufferedOutputStream output =
|
||||
new BufferedOutputStream(new FileOutputStream(file));
|
||||
writer.setOutput(ImageIO.createImageOutputStream(output));
|
||||
writer.write(null, new IIOImage(bimage, null, null), param);
|
||||
writer.dispose();
|
||||
|
||||
output.flush();
|
||||
output.close();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if ((writer = imageioWriter("png")) != null) {
|
||||
param = writer.getDefaultWriteParam();
|
||||
metadata = imageioDPI(writer, param, 100);
|
||||
}
|
||||
if (writer != null) {
|
||||
BufferedOutputStream output =
|
||||
new BufferedOutputStream(PApplet.createOutput(file));
|
||||
writer.setOutput(ImageIO.createImageOutputStream(output));
|
||||
// writer.write(null, new IIOImage(bimage, null, null), param);
|
||||
writer.write(metadata, new IIOImage(bimage, null, metadata), param);
|
||||
writer.dispose();
|
||||
|
||||
output.flush();
|
||||
output.close();
|
||||
return true;
|
||||
}
|
||||
// If iter.hasNext() somehow fails up top, it falls through to here
|
||||
return javax.imageio.ImageIO.write(bimage, extension, file);
|
||||
|
||||
@@ -3135,6 +3139,52 @@ public class PImage implements PConstants, Cloneable {
|
||||
}
|
||||
|
||||
|
||||
private ImageWriter imageioWriter(String extension) {
|
||||
Iterator<ImageWriter> iter = ImageIO.getImageWritersByFormatName(extension);
|
||||
if (iter.hasNext()) {
|
||||
return iter.next();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
private IIOMetadata imageioDPI(ImageWriter writer, ImageWriteParam param, double dpi) {
|
||||
// http://stackoverflow.com/questions/321736/how-to-set-dpi-information-in-an-image
|
||||
ImageTypeSpecifier typeSpecifier =
|
||||
ImageTypeSpecifier.createFromBufferedImageType(BufferedImage.TYPE_INT_RGB);
|
||||
IIOMetadata metadata =
|
||||
writer.getDefaultImageMetadata(typeSpecifier, param);
|
||||
|
||||
if (!metadata.isReadOnly() && metadata.isStandardMetadataFormatSupported()) {
|
||||
// for PNG, it's dots per millimeter
|
||||
double dotsPerMilli = dpi / 25.4;
|
||||
|
||||
IIOMetadataNode horiz = new IIOMetadataNode("HorizontalPixelSize");
|
||||
horiz.setAttribute("value", Double.toString(dotsPerMilli));
|
||||
|
||||
IIOMetadataNode vert = new IIOMetadataNode("VerticalPixelSize");
|
||||
vert.setAttribute("value", Double.toString(dotsPerMilli));
|
||||
|
||||
IIOMetadataNode dim = new IIOMetadataNode("Dimension");
|
||||
dim.appendChild(horiz);
|
||||
dim.appendChild(vert);
|
||||
|
||||
IIOMetadataNode root = new IIOMetadataNode("javax_imageio_1.0");
|
||||
root.appendChild(dim);
|
||||
|
||||
try {
|
||||
metadata.mergeTree("javax_imageio_1.0", root);
|
||||
return metadata;
|
||||
|
||||
} catch (IIOInvalidTreeException e) {
|
||||
System.err.println("Could not set the DPI of the output image");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
protected String[] saveImageFormats;
|
||||
|
||||
/**
|
||||
|
||||
@@ -12,6 +12,12 @@ X getFloatContent()
|
||||
X getContent() or getStringContent()?
|
||||
X switch to CATEGORY instead of CATEGORICAL
|
||||
X removed createXML() and createTable()... just use 'new' for these
|
||||
X implement means for setting dpi in PNG images
|
||||
X need to add something for API yet
|
||||
o JAI handles setting image size for png (check javax.imageio?)
|
||||
o PNGEncodeParam png = PNGEncodeParam.getDefaultEncodeParam(bufImage);
|
||||
o png.setPhysicalDimension(round(dpi*39.370079), round(dpi*39.370079), 1);
|
||||
o JAI.create("filestore", bufImage, filename+".png", "PNG");
|
||||
|
||||
mouse wheel
|
||||
X add mouse wheel support to 2.0 event system
|
||||
@@ -44,6 +50,13 @@ X ref: "negative values if the mouse wheel was rotated up or away from the use
|
||||
X http://docs.oracle.com/javase/6/docs/api/java/awt/event/MouseWheelEvent.html#getWheelRotation()
|
||||
X http://docs.oracle.com/javase/7/docs/api/java/awt/event/MouseWheelEvent.html#getWheelRotation()
|
||||
|
||||
_ add options for image.save() (or sageImage?)
|
||||
_ add quality=[0,1] for jpeg images
|
||||
_ add dpi=[0,n] for for png images
|
||||
|
||||
_ PImage.loadPixels() shouldn't be calling out to the renderer
|
||||
_ setting image.parent = null for it makes it work again for get().save() case
|
||||
_ PShape should be cached as well
|
||||
|
||||
before release
|
||||
_ "deleted n framebuffer objects"
|
||||
|
||||
Reference in New Issue
Block a user