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



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

编辑#1:将要创建的图像的大小是可变的,因此我正在寻找内存使用方面的有效方法,以便在创建图像时免受Javaheap space异常的影响。

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

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

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

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")));

这里有一些非常简单的示例代码,据我所知,它们应该符合您的需求。该程序应该在几乎没有内存的情况下非常高效地工作,但仍然可以创建大小高达(大约)2GB的图像文件(如果你愿意,你也可以很容易地调整它来创建更大的图像)。

假设:

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

输入是文件大小,后跟文件名(要使用.pgm作为扩展名)。例如:

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

以上内容将创建JVM允许读取的最大映像,大约为2GB。

代码:

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("P5n".getBytes(StandardCharsets.UTF_8));
// Dimensions (width/height)
out.write(String.format("%s 1n", size).getBytes(StandardCharsets.UTF_8));
// MaxSample
out.write("255n".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或我自己的PNM插件,但您当然会遇到与尝试使用Java2D(BufferedImage)生成此类图像时相同的内存问题。


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

也许你可以用额外的非图像数据填充一个最小的JPEG,比如XMP。PNG确实允许在没有压缩的情况下写入Deflate块,这可能是一种选择。或者使用额外的填充块。

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

  • BufferedImage
  • 使用图像
  • Graphics 2D

例如

相关内容

  • 没有找到相关文章

最新更新