【问题标题】:Thumbnail creation in JavaJava中的缩略图创建
【发布时间】:2011-07-24 06:02:21
【问题描述】:

我想为一组图像创建缩略图。为此,我正在使用以下代码。

public void run() {
        try{
    BufferedImage originalImage = ImageIO.read(new File(url));
    int type = originalImage.getType() == 0? BufferedImage.TYPE_INT_ARGB : originalImage.getType();
            IMG_HEIGHT = (originalImage.getHeight()*600)/originalImage.getWidth();
    BufferedImage resizeImageJpg = resizeImage(originalImage, type);
    ImageIO.write(resizeImageJpg, "jpg", new File(thumb));
            originalImage.flush();
            resizeImageJpg.flush();
            System.gc();

}catch(IOException e){
    System.out.println(e.getMessage());
            System.out.println("Not Created:"+url);
}
    }
private static BufferedImage resizeImage(BufferedImage originalImage, int type){
BufferedImage resizedImage = new BufferedImage(IMG_WIDTH, IMG_HEIGHT, type);
Graphics2D g = resizedImage.createGraphics();
g.drawImage(originalImage, 0, 0, IMG_WIDTH, IMG_HEIGHT, null);
g.dispose();
    System.gc();
return resizedImage;
}

此代码工作正常并创建缩略图。但问题是,在大量图像的情况下,我得到“java heap space error”。是这段代码的问题吗?我该如何解决这个问题。提前致谢。 如果您有任何其他调整大小的代码,请给我。

【问题讨论】:

  • 看来你已经用完了堆空间。使用用于读取所有图像的 cicle 完成代码

标签: java resize thumbnails


【解决方案1】:

试试这个图像缩放库,它对我来说很好用。

http://www.thebuzzmedia.com/software/imgscalr-java-image-scaling-library/

【讨论】:

  • 很高兴它对你有用;我写它的全部原因是为了非常容易和非常快速地解决这种情况(OP):“我想要缩略图,为我制作计算机!”该库有一些比这更高级的功能,但仅此而已。我确保它尽可能简单/小,这样它就不会失去范围并成为另一个通用图形 API。
【解决方案2】:

您如何启动此流程?这段代码似乎确实正确地清理了图像。

唯一的选择是通过添加 -Xmx 512m(例如将堆大小增加到 512 MB)作为 VM 命令行选项之一来增加堆大小。

【讨论】:

  • 我也是这样做的。但这不是正确的解决方案。
  • 图片的尺寸(和分辨率)是多少?如果图像很大,那么您必须确保有足够的堆来同时加载 3 - 4 张图像
  • 输入图像来自文件选择器。只有当我们选择超过 15 个图像时,我才会收到堆空间错误。我正在运行一个从 0 到 no 的 for 循环。选定的图像。在该循环中,我调用上述函数来创建缩略图。
  • 这些图片的平均尺寸/分辨率是多少?还是不管分辨率如何都会发生这种情况?
【解决方案3】:

在 Java 中创建缩略图需要相应的工具:ImageMagick

从 Java 调用它,然后享受结果。它总是比您在 Java 中使用可用库所做的一切更好、更安全、更快速。

【讨论】:

    【解决方案4】:

    我看不到您在哪里设置 IMG_WIDTH,可能是它留下了巨大的价值。您应该更喜欢将目标宽度和高度作为参数传递,您设置高度的方式可防止多线程使用并使其难以阅读。而且我怀疑目标图像的高度是否真的是对象状态的一部分。

    另外,您确定您正确设置了图像高度吗?高度与高度和宽度之间的比例有关,如果目标图像的宽度为保持不变。

    最后一件事,http://www.jhlabs.com/ip/filters/index.html 有一些有用的图像处理代码(包括调整大小),我已经用过很多次了。

    假设您的图像很大,您可能需要查看 JAI 并使用嵌入式缩略图或子采样来减少所需的内存。

    public static BufferedImage getThumb(ImageReader reader, int size) throws IOException {
        BufferedImage img;
    
        try {
            if (reader.getNumThumbnails(0) > 0) {
                img = reader.readThumbnail(0, 0);
            } else {
                ImageReadParam param = reader.getDefaultReadParam();
                param.setSourceSubsampling(4, 4, 0, 0);
                img = reader.read(0); //read(0, param);
            }
            throw new Exception();
        } catch (Throwable t) {
            img = null;
        }
    
        return img != null ? resizeImage(img, size) : null;
    }   
    
    public static BufferedImage getThumb(File file, double scale) throws IOException {
        BufferedImage img = null;
    
        try {
            Class<?> c = ImageUtil.class.getClassLoader().loadClass("javax.media.jai.JAI");
            Class<?> ic = ImageUtil.class.getClassLoader().loadClass("javax.media.jai.Interpolation");
            Class<?> sc = ImageUtil.class.getClassLoader().loadClass("javax.media.jai.operator.ScaleDescriptor");
            Method jaiCreate = c.getMethod("create", String.class, Object.class);
            Method getInstance = findMethod(ic, "getInstance");
            Method sdCreate = findMethod(sc, "create");
    
            if (c != null) { 
                Object image = jaiCreate.invoke(null, "fileload", file.getAbsolutePath());              
                Object[] params = { image, (float) scale, (float) scale,
                        0.0f, 0.0f, getInstance.invoke(null, 2), null };
                Object sd = sdCreate.invoke(null, params);
                Method m = sd.getClass().getMethod("getAsBufferedImage");
                img = (BufferedImage) m.invoke(sd);
            }
        } catch (Throwable tt) {
            System.out.println("Could not read image using JAI, maybe JAI is not installed.");
            System.out.println(tt);
        }
    
        return img;
    }
    

    【讨论】:

    • 我从函数外部将 IMG_WIDTH 静态设置为 600。
    • 您输入的图像是多大(尺寸方面),它们总是具有固定的纵横比吗?如果不是,您最终会得到一些拉伸的图像。
    • 我明白你的意思。但主要问题是堆空间错误。
    • 您的输入图像的尺寸(尺寸)是多少?如果您的源图像和目标图像很大,那么您将耗尽内存并影响解决方案。
    【解决方案5】:

    【讨论】:

      猜你喜欢
      • 2011-02-20
      • 2011-02-18
      • 2012-03-19
      • 2012-02-04
      • 1970-01-01
      • 2010-11-07
      • 2010-11-15
      • 2013-10-22
      • 1970-01-01
      相关资源
      最近更新 更多