Ich denke, es gibt Zeiten, in denen Sie die Größe eines JPEG-Bildes ändern und es speichern möchten. Wenn Sie ImageMagick verwenden können, ist die Geschichte schnell, aber wenn Sie sie wirklich nur mit Java vervollständigen möchten, verwenden Sie ImageIO.
Beachten Sie jedoch, dass die einfachste Implementierungsmethode die Speicherqualität des JPEG-Bilds automatisch auf "75" setzt (überprüfen Sie dies mit Java 8). Ich war süchtig danach.
Die Implementierung selbst ist einfach, aber wenn Sie die Speicherqualität ändern möchten, ist dies NG.
public static byte[] resize(final byte[] src, final double scale) throws IOException {
try (ByteArrayInputStream is = new ByteArrayInputStream(src);
ByteArrayOutputStream os = new ByteArrayOutputStream()) {
BufferedImage srcImage = ImageIO.read(is);
BufferedImage destImage = resizeImage(srcImage, scale);
//Die Speicherqualität beträgt "75".
ImageIO.write(destImage, "jpeg", os);
return os.toByteArray();
}
}
Dies ist die richtige Antwort. Sie können die Speicherqualität "Qualität" von 0 bis 1,0 angeben. 1,0 entspricht der Qualität 100.
public static byte[] resize(final byte[] src, final double scale, final float quality) throws IOException {
try (ByteArrayInputStream is = new ByteArrayInputStream(src);
ByteArrayOutputStream os = new ByteArrayOutputStream();
ImageOutputStream ios = ImageIO.createImageOutputStream(os)) {
BufferedImage srcImage = ImageIO.read(is);
BufferedImage destImage = resizeImage(srcImage, scale);
//Die Speicherqualität entspricht den Benutzerspezifikationen
ImageWriter writer = ImageIO.getImageWritersByFormatName("jpeg").next();
ImageWriteParam param = writer.getDefaultWriteParam();
param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
param.setCompressionQuality(quality);
writer.setOutput(ios);
writer.write(null, new IIOImage(destImage, null, null), param);
writer.dispose();
return os.toByteArray();
}
}
Die Implementierung der Größenänderungsmethode "resizeImage", die in den beiden vorherigen Beispielen angezeigt wird, ist wie folgt. Die Bildqualität ist beim Ändern der Bildgröße standardmäßig nicht gut. Sie können die Bildqualität jedoch verbessern, indem Sie bei der Konvertierung in Affin "TYPE_BICUBIC" angeben.
public static BufferedImage resizeImage(final BufferedImage image, final double scale) throws IOException {
int width = (int) (image.getWidth() * scale);
int height = (int) (image.getHeight() * scale);
BufferedImage resizedImage = new BufferedImage(width, height, image.getType());
//Größenänderung durch affine Konvertierung (Priorität hat die Bildqualität)
AffineTransform transform = AffineTransform.getScaleInstance(scale, scale);
AffineTransformOp op = new AffineTransformOp(transform, AffineTransformOp.TYPE_BICUBIC);
op.filter(image, resizedImage);
return resizedImage;
}
Bei der Größenänderung in Java wird die Speicher- und CPU-Auslastung unannehmbar groß, wenn die Bilddaten groß werden. Daher denke ich, dass die Szenen, die verwendet werden können, sehr begrenzt sind.
Recommended Posts