sti*_*vlo 19 java java-2d image-resizing scalr
我正在尝试使用Java和Scalr 3.2创建此图像的高质量缩略图

这是相关的源代码,其中THUMB_WIDTH = 77和THUMB_HEIGHT = 57
BufferedImage srcImg = ImageIO.read(new File(sourceFile));
BufferedImage dstImg = Scalr.resize(srcImg, Scalr.Method.QUALITY,
THUMB_WIDTH, THUMB_HEIGHT);
ImageIO.write(dstImg, format, new File(destFile));
Run Code Online (Sandbox Code Playgroud)
如果我使用format = "png",结果如下:

如果我使用format = "jpg",结果如下:

通过imagemagick识别,我发现JPEG的质量保存为75,完全不足以创建美观的缩略图.PNG对我来说也不好看.
以下是原始文件的标识输出和两个缩略图:
$ identify 42486_1.jpg 42486_s1.jpg 42486_s1.png
42486_1.jpg JPEG 580x435 580x435+0+0 8-bit DirectClass 50.6KB 0.000u 0:00.000
42486_s1.jpg[1] JPEG 77x58 77x58+0+0 8-bit DirectClass 2.22KB 0.000u 0:00.000
42486_s1.png[2] PNG 77x58 77x58+0+0 8-bit DirectClass 12.2KB 0.000u 0:00.000
Run Code Online (Sandbox Code Playgroud)
更新:通过网络搜索,我找到了一篇关于如何调整JPEG图像压缩质量的文章.我编写了自己的方法来保存BufferedImage设置的质量:
/**
* Write a JPEG file setting the compression quality.
*
* @param image
* a BufferedImage to be saved
* @param destFile
* destination file (absolute or relative path)
* @param quality
* a float between 0 and 1, where 1 means uncompressed.
* @throws IOException
* in case of problems writing the file
*/
private void writeJpeg(BufferedImage image, String destFile, float quality)
throws IOException {
ImageWriter writer = null;
FileImageOutputStream output = null;
try {
writer = ImageIO.getImageWritersByFormatName("jpeg").next();
ImageWriteParam param = writer.getDefaultWriteParam();
param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
param.setCompressionQuality(quality);
output = new FileImageOutputStream(new File(destFile));
writer.setOutput(output);
IIOImage iioImage = new IIOImage(image, null, null);
writer.write(null, iioImage, param);
} catch (IOException ex) {
throw ex;
} finally {
if (writer != null) writer.dispose();
if (output != null) output.close();
}
}
Run Code Online (Sandbox Code Playgroud)
结果如下.PNG:

JPEG品质75:

JPEG质量90(stackoverflow上的gravatars保存为JPEG质量90):

和文件大小:
thumb90.jpg JPEG 77x58 77x58+0+0 8-bit DirectClass 6.89KB 0.000u 0:00.000
Run Code Online (Sandbox Code Playgroud)
更新2:测试将Scalr与java-image-scaling进行比较.
private void scaleAndSaveImageWithScalr(String sourceFile, String destFile, int width, int height)
throws IOException {
BufferedImage sourceImage = ImageIO.read(new File(sourceFile));
BufferedImage destImage = Scalr.resize(sourceImage, Scalr.Method.QUALITY, width, height);
writeJpeg(destImage, destFile, JPEG_QUALITY);
}
private void scaleAndSaveImageWithJImage(String sourceFile, String destFile, int width, int height)
throws IOException {
BufferedImage sourceImage = ImageIO.read(new File(sourceFile));
ResampleOp resampleOp = new ResampleOp(width, height);
resampleOp.setFilter(ResampleFilters.getLanczos3Filter());
resampleOp.setUnsharpenMask(AdvancedResizeOp.UnsharpenMask.Normal);
BufferedImage destImage = resampleOp.filter(sourceImage, null);
writeJpeg(destImage, destFile, JPEG_QUALITY);
}
Run Code Online (Sandbox Code Playgroud)
使用Scalr生成的JPEG质量90:

使用java-image-scaling生成的JPEG质量90:

我没有收到任何进一步的反馈,所以我个人的结论是java-image-scaling提供了卓越的质量,所以它是我选择的库.
这不是您问题的完整答案,但是:
\n\n关于 JPEG 质量:
\n\n可以使用此处所述的ImageWriteParam设置压缩质量。他们建议使用0|1 值,但我相信您实际上应该指定 0.0 和 1.0 之间的浮点值。int
关于缩放尺寸问题:
\n\n来自Scalr 主页:
\n\n\n\n\n注意:如果提供的宽度和高度违反了图像\xe2\x80\x99s\n 比例(例如,尝试将 800\xc3\x97600 图像调整为 150\xc3\x97150\n 正方形),则库将首先查看在图像的方向\n(横向/方形或纵向),然后\n选择主要尺寸\n(横向或方形使用宽度,纵向使用高度)以重新计算\n正确的次要尺寸;忽略用户传入的内容违反比例的内容。
\n
在您的情况下,主要尺寸将为宽度 77,因此您的高度限制 57 将被忽略。
\n| 归档时间: |
|
| 查看次数: |
12307 次 |
| 最近记录: |