如何在Java中生成特定大小的图像?

时间:2017-02-05 21:48:00

标签: java file image-processing graphics java-io

我需要生成给定大小的图像(图像格式无关紧要)(例如,10KB100KB1MB10MB等),使用 Java 。图像可以是填充背景颜色的任何形状,对图像内容没有限制。

编辑#1:要创建的图片大小可以更改,因此我在内存方面寻找一种有效的方法用法,以便在创建图片时远离 Java heap space例外。

编辑#2:当我尝试使用Graphics2D库生成尺寸为java.lang.IllegalArgumentException: Dimensions (width=48000 height=48000) are too large的图像时,我收到了48000x48000异常,这对于生成大文件大小的图像。

编辑#3:当维度变大时,即使我手动配置执行此操作的Java程序的java.lang.OutOfMemoryError: Java heap space参数,我也会遇到-Xmx异常。

3 个答案:

答案 0 :(得分:1)

根据我的理解,这里有一些非常简单的示例代码,可以满足您的要求。该程序应该可以非常有效地工作,几乎没有内存,但仍然会创建大小(大约)2GB的图像文件(如果你愿意,你也可以轻松地调整它以创建更大的图像)。

假设:

  • 图片格式无关紧要,因此我们选择PGM format(二进制'P5'模式)
  • 图像可以是任何形状/颜色,所以我们只做最简单的事情并写下一行全黑。
  • 重要的大小是图像文件大小(下面的代码不会写入此大小的字节,但可以通过在写入之前减去最小文件头的大小来轻松修改)。

输入是文件大小,后跟文件名(您希望使用.pgm作为扩展名)。举个例子:

$ java -cp ... WritePGM 2147483640 foo.pnm

以上将创建我的JVM允许回读的最大可能图像,大约为2 GB。

代码:

public class WritePGM {
    public static void main(String[] args) throws IOException {

        int size = Integer.parseInt(args[0]);
        File file = new File(args[1]);

        try (OutputStream out = new BufferedOutputStream(new FileOutputStream(file))) {
            // Format P5/binary gray
            out.write("P5\n".getBytes(StandardCharsets.UTF_8));
            // Dimensions (width/height)
            out.write(String.format("%s 1\n", size).getBytes(StandardCharsets.UTF_8));
            // MaxSample
            out.write("255\n".getBytes(StandardCharsets.UTF_8));

            // Just write a single line of 0-bytes
            for (int i = 0; i < size; i++) {
                out.write(0);
            }
        }
    }
}

PS:如果你需要一个ImageIO插件来使用Java读取生成的文件,你可以使用JAI ImageIO或my own PNM plugin,但你当然会遇到与尝试使用Java生成此类图像时相同的内存问题Java2D(BufferedImage)。

理论上,您也可以使用类似的技术来创建JPEG或PNG等格式的文件,但这些格式很多难以实现。此外,它们是压缩的,因此预测文件大小很难。

也许你可以使用额外的非图像数据填充最小的JPEG,如XMP左右。 PNG允许编写没有压缩的Deflate块,这可能是一个选项。或者使用额外的块来填充。

像BMP这样的未压缩格式会更简单。您可以使用与上面相同的技术,只需编写一个固定的,最小的BMP标头,设置正确的宽度并按照上面的方式写入图像数据。 BMP确实需要行填充,并且不支持灰色数据,因此您需要做一些额外的工作。但肯定可行。

答案 1 :(得分:0)

生成灰度图像(宽度:宽度和高度:高度)的一种方法: -

1)创建一个BufferedImage对象: -

BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GRAY);

2)填充你的BufferedImage对象(这里我假设你对存储在一个名为img的二维int数组中的图像有适当的输入): -

for (int y = 0; y < image.getHeight(); y++) 
    {
      for (int x = 0; x < image.getWidth(); x++) 
      {

          image.setRGB(x, y, img[y][x]<<16 | img[y][x] << 8 | img[y][x]);
      }

    }

3)将BufferedImage对象写入磁盘: -

ImageIO.write(image, "jpg", new FileOutputStream(new File("SomePath/Name-of-Image.jpg")));

答案 2 :(得分:-2)