如何获得高质量的缩略图 [英] How to get a good quality thumbnail
问题描述
我正在尝试使用Java和我发现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位DirectClass 2.22KB 0.000u 0:00.000
42486_s1.png [2] PNG 77x58 77x58 + 0 + 0 8位DirectClass 12.2KB 0.000u 0:00.000
问题
- 如何提高生成的缩略图的质量?
- 如何保存质量更高的JPEG?我想尝试更高的质量并比较结果。我在JavaDoc for ImageIO.write中找不到任何东西。
- 为什么我告诉Scalr我的最大尺寸是77x57并输出图像77x58?我认为这是保持比例,但那是我的最大宽度和最大高度。宽度或高度可以更小但不能更多。
更新:通过网络搜索我找到了一篇文章关于如何。
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(源文件));
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);
}
使用Scalr生成的JPEG质量90:
使用java-image-scaling生成的JPEG质量90:
我没有收到任何进一步的反馈,所以我的个人结论是java-image-scaling提供了卓越的品质,所以这是我选择的图书馆。
这不是你问题的完整答案,但是:
关于JPEG质量:
可以使用设置压缩质量ImageWriteParam
as 此处描述。他们建议使用 int
值0 | 1,但我相信你应该实际指定一个介于0.0和1.0之间的浮点值。
关于缩放尺寸问题:
来自 Scalr主页:
注意:如果提供的宽度和高度违反图像的
比例(例如尝试将800×600图像调整为150×150
方格)图书馆将首先查看图像的方向
(横向/正方形或纵向)然后
选择主尺寸
(横向或方形使用宽度,纵向使用高度)重新计算
a正确的次要尺寸; 忽略违反比例的用户传入的内容
。
在你的如果主要尺寸的宽度为77,则高度限制为57将被忽略。
I am trying to create a high quality thumbnail of this image, with Java and Scalr 3.2
This is the relevant source code, where THUMB_WIDTH = 77
and 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));
If I use format = "png"
, here is the result:
If I use format = "jpg"
, here is the result:
With imagemagick identify I've found out that the JPEG is saved with a quality of 75 that is totally insufficient to create a good looking thumbnail. The PNG doesn't look good either to me.
Here is the output of identify of the original file and the two thumbnails:
$ 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
Questions
- How to improve the quality of the generated thumbnail?
- How to save a JPEG with a higher quality? I'd like to try with higher quality and compare the results. I couldn't find anything in the JavaDoc for ImageIO.write.
- Why I tell Scalr that my maximum dimensions are 77x57 and it output an image 77x58? I think that is to maintain the proportion, but those are my maximum width and maximum height. Width or height could be less but not more.
UPDATE: With a web search I found an article about how to adjust JPEG image compression quality. I wrote my own method to save a BufferedImage setting the quality:
/**
* 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();
}
}
Here are the results. PNG:
JPEG quality 75:
JPEG quality 90 (the gravatars on stackoverflow are saved as JPEG quality 90):
and the filesize:
thumb90.jpg JPEG 77x58 77x58+0+0 8-bit DirectClass 6.89KB 0.000u 0:00.000
UPDATE 2: test to compare Scalr with 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);
}
JPEG quality 90 generated with Scalr:
JPEG quality 90 generated with java-image-scaling:
I didn't receive any further feedback, so my personal conclusion is that java-image-scaling provides superior quality, and so it's the library that I choose.
This is not a complete answer to your question, but:
Regarding JPEG quality:
Compression quality can be set using a ImageWriteParam
as described here. They suggest using an int
value of 0|1 but I believe that you should actually specify a float value between 0.0 and 1.0.
Regarding your scaling dimension issues:
From the Scalr homepage:
NOTE: If a width and height are provided that violate the image’s proportions (e.g. attempt to resize an 800×600 image to a 150×150 square) the library will first look at the orientation of the image (landscape/square or portrait) and then select the primary dimension (landscape or square uses width, portrait uses height) to recalculate a correct secondary dimension; ignoring what was passed in by the user that was violating the proportions.
In your case the primary dimension will be a width of 77 and thus your height limit of 57 will be ignored.
这篇关于如何获得高质量的缩略图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!