【问题标题】:Unable to create thumbnails for large image files无法为大图像文件创建缩略图
【发布时间】:2011-08-12 01:00:54
【问题描述】:

我是图形新手。我一直在使用此代码制作图像文件的缩略图。当我使用像墙纸这样的小文件(~100KB)时,它可以正常工作,但是当我使用大小约为 5MB 的图像文件(照片)时,它只会产生几个字节(~1-8KB)的文件,显示为黑色图像。我给它的宽度和高度都没有关系。这里可能出了什么问题?是图像类型还是产生图像的相机之间的区别?我确信问题图像来自与没有问题的图像不同的相机。我将质量参数设为 100,以免错过任何细节......

        ByteArrayOutputStream out = new ByteArrayOutputStream();
    try {
        int dx = thumbWidth, dy = thumbHeight; 

        Image image = Toolkit.getDefaultToolkit().createImage(file);
        MediaTracker mediaTracker = new MediaTracker(new Container());
        mediaTracker.addImage(image, 0);
        mediaTracker.waitForID(0);

        double thumbRatio = (double)thumbWidth / (double)thumbHeight;

        int imageWidth = image.getWidth(null);
        int imageHeight = image.getHeight(null);
        double imageRatio = (double)imageWidth / (double)imageHeight;

        if (thumbRatio < imageRatio) {
          thumbHeight = (int)(thumbWidth / imageRatio);
        } else {
          thumbWidth = (int)(thumbHeight * imageRatio);
        }

        if(thumbWidth > dx) {
            thumbWidth = dx;
            thumbHeight = (int)(thumbWidth / imageRatio);
        }
        if(thumbHeight > dy)
        {
            thumbHeight = dy;
            thumbWidth = (int) (thumbHeight*imageRatio);
        }

        log.debug("X="+thumbWidth+" Y="+thumbHeight);

        BufferedImage thumbImage = new BufferedImage(thumbWidth, thumbHeight, BufferedImage.TYPE_INT_RGB);
        Graphics2D graphics2D = thumbImage.createGraphics();
        graphics2D.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
        graphics2D.drawImage(image, 0, 0, thumbWidth, thumbHeight, null);

        JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
        JPEGEncodeParam param = encoder.getDefaultJPEGEncodeParam(thumbImage);

        quality = Math.max(0, Math.min(quality, 100));
        param.setQuality((float)quality / 100.0f, false);

        encoder.setJPEGEncodeParam(param);
        encoder.encode(thumbImage);
        log.debug("ThumbLength"+out.toByteArray().length);

        FileOutputStream fos = new FileOutputStream("/root/testx.jpg");
        fos.write(out.toByteArray());
        fos.close();

    } catch(Exception e) { log.debug(e.getMessage());}

    return out.toByteArray(); 

【问题讨论】:

    标签: java image graphics jpeg


    【解决方案1】:

    你可以试试BufferedImage.TYPE_INT_ARGB,如图here

    另外,您的MediaTracker 正在同一个线程上等待; ImageIO.read() 可能更简单。

    附录:还要考虑AffineTransformOp,尽管srcdst 必须不同。

    【讨论】:

    • @trashgod 感谢您的回复。我试过了,可能我需要做的不仅仅是简单地改变你所说的,但我现在得到的图像要么是黑色的,要么是橙色的。但是我发现了一些新东西...代码中存在内存使用问题...
    • 无法发布所有日志...我正在使用带有 java 1.5 的 tomcat 6.0.18。我在 OS X 和 fedora 8 上使用过这段代码。线程“Image Fetcher 0”中的异常 java.lang.OutOfMemoryError: Java heap space at java.awt.image.DataBufferInt.(DataBufferInt.java:41 ) 在 java.awt.image.Raster.createPackedRaster(Raster.java:458) 在 java.awt.image.DirectColorModel.createCompatibleWritableRaster(DirectColorModel.java:1015) 在 sun.awt.image.ImageRepresentation.createBufferedImage(ImageRepresentation.java: 230) 在 sun.awt.image.ImageRepresentation.setPixels(ImageRepresentation.java:535)
    • 是的,TYPE_BICUBIC 占用大量内存。您必须凭经验确定合适的限制并拒绝相应大小的图像。在一批 100 MiB 的图像中,我需要超过 1 GiB 的内存——比例为 10:1。作为替代方案,您可以尝试AffineTransformOp
    • 更正:它们是 100 兆像素的图像,具有 16 位/像素。一个 200 MiB 的图像需要 1024 MiB 的内存——比例为 5:1。
    • @Ram:不客气。仔细看,我看到你调用了createGraphics();除了paint(),这需要一个对应的dispose()。更多here.
    猜你喜欢
    • 2014-04-09
    • 1970-01-01
    • 1970-01-01
    • 2015-01-19
    • 2013-06-22
    • 2013-06-24
    • 2017-09-03
    • 2011-11-01
    • 1970-01-01
    相关资源
    最近更新 更多