首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何获得高质量的缩略图

如何获得高质量的缩略图
EN

Stack Overflow用户
提问于 2011-10-12 23:02:33
回答 5查看 13.2K关注 0票数 19

我试图创建此图像的高质量缩略图,与Java和Scalr 3.2

这是相关的源代码,其中THUMB_WIDTH = 77THUMB_HEIGHT = 57

代码语言:javascript
复制
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));

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

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

使用imagemagick identify,我发现JPEG75的质量完全不足以创建一个好看的缩略图。PNG在我看来也不是很好。

以下是原始文件的identify和两个缩略图的输出:

代码语言:javascript
复制
$ 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

问题

  • 如何提高生成的缩略图的质量?
  • 如何保存具有更高质量的JPEG?我想尝试更高质量的,并比较结果。我在ImageIO.write的JavaDoc中找不到任何东西。
  • 为什么我告诉Scalr我的最大尺寸是77x57,而它输出的图像是77x58?我认为这是为了保持比例,但这些都是我的最大宽度和最大高度。宽度或高度可以更小,但不能更大。

更新:通过网络搜索,我找到了一篇关于如何adjust JPEG image compression quality的文章。我编写了自己的方法来保存BufferedImage设置的质量:

代码语言:javascript
复制
/**
 * 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();
    }
}

以下是结果。PNG:

JPEG质量75:

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

和文件大小:

代码语言:javascript
复制
thumb90.jpg JPEG 77x58 77x58+0+0 8-bit DirectClass 6.89KB 0.000u 0:00.000

更新2:测试比较Scalr和java-image-scaling

代码语言:javascript
复制
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);
}

使用Scalr生成的JPEG质量90:

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

我没有收到任何进一步的反馈,所以我个人的结论是java-image-scaling提供了卓越的质量,所以我选择了这个库。

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2011-10-12 23:09:26

这并不是对您问题的完整回答,但是:

关于JPEG质量的

可以使用ImageWriteParam作为described here来设置压缩质量。他们建议使用0|1的int值,但我认为您实际上应该指定一个介于0.0和1.0之间的浮点值。

关于您的缩放维度问题的

Scalr homepage

注意:如果提供的宽度和高度违反了图像的比例(例如,试图将800×600图像调整为150×150正方形),库将首先查看图像的方向(横向/正方形或纵向),然后选择主要维度(横向或正方形使用宽度,纵向使用高度)来重新计算正确的二级尺寸;忽略用户传入的违反比例的内容。

在您的情况下,主要尺寸将是77的宽度,因此您的高度限制57将被忽略。

票数 1
EN

Stack Overflow用户

发布于 2012-12-31 01:51:52

@Stivlo,我很抱歉没有回复这个问题,我从来没有收到任何关于这个问题的通知。

如果您需要的话,java-image-scaling确实有一些很好的过滤器来帮助您进行微调。也就是说,在imgscalr的4.2版本中,我添加了新的ULTRA_QUALITY,它可能会让你更接近你想要的东西。

我希望这会有所帮助,但不幸的是,我意识到这是在事件发生近一年后才回复的。真对不起。

票数 2
EN

Stack Overflow用户

发布于 2012-03-21 06:31:38

我已经运行了相同的测试,java-image-scaling对于小于250px的缩略图肯定有更好的结果。它还支持锐化过滤,从而使结果更好。

我保留了这两个库,因为Scalr的语法通常更简单,只有一行。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7742175

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档