【问题标题】:Generate Image Files of Arbitrary File Size生成任意文件大小的图像文件
【发布时间】:2025-12-02 03:35:01
【问题描述】:

对于我正在进行的网络实验,我需要任意大小的图像文件。

我不知道如何创建此类文件。我需要 JPEG、PNG 和 PDF 格式的 5MB、10MB 和 20MB 文件。

在我第一次尝试生成这些文件时,很明显由于这些格式的压缩方案,仅通过指定空白分辨率来生成任意大小的文件是不可能的(或者至少我不知道如何)文件。

是否有一种快速(程序化?)方法可以生成这些文件?

编辑:我正在研究创建任意大小的虚拟文件,但如果有办法创建具有正确内部格式的实际 JPEG、PNG 或 PDF,那将是理想的。

【问题讨论】:

    标签: image image-manipulation


    【解决方案1】:

    这只是一个建议。不知道它是否会起作用。

    也许您可以生成正确大小的位图并进行转换?

    如果你让位图很难压缩(1)?然后,您应该能够将它们转换为非常接近目标大小的 jpg 和 png。

    (1) 我的建议是,这可以通过将位图中的每个像素设置为不同的颜色来实现(尽可能)

    编辑:
    这个简单的解决方案可能不适用于 jpg,但至少 png 似乎可以工作。

    我在 c# 中编写了一个小 testapp 来尝试一下。这是它的肉:

    private void make_bitmap(int width, int height)
    {
        Random random = new Random();
        Bitmap B = new Bitmap(width, height);
        int redvalue = 0;
        int greenvalue = 0;
        int bluevalue = 0;
    
        bool pick_random_color = true;
        for (int x = 0; x < width; x++)
        {
            for (int y = 0; y < width; y++)
            {
                Color col;
                if (pick_random_color)
                {
                   col = Color.FromArgb(random.Next(0, 255), random.Next(0, 255), random.Next(0, 255));
                }
                else  // iterate over all colours repeatedly
                {   
                    if (redvalue == 255) { redvalue = 0; greenvalue++; } else { redvalue++; }
                    if (greenvalue == 256) { greenvalue = 0; bluevalue++; }
                    if (bluevalue == 256) { redvalue = 0; greenvalue = 0; bluevalue = 0; }
                    col = Color.FromArgb(redvalue, greenvalue, bluevalue);
                }
                B.SetPixel(x, y, col);
            }
        }
        B.Save("image.bmp");
        B.Save("image.jpg", ImageFormat.Jpeg);
        B.Save("image.png", ImageFormat.Png);
        B.Dispose();
    }
    

    【讨论】:

    • 我喜欢这个答案。然而,说起来容易做起来难。我希望这里的某个人会知道如何实施您的建议。我确实尝试过模拟一个适当大小的渐变(在此过程中使用了 32 位的颜色),但不知道 JPEG 或 PNG 压缩方案的内部结构,我不知道我是否做得足够好。他们设法把它压缩了很多。
    • 我很快就试过了。它似乎适用于png,但不适用于jpg。 png 与位图的大小几乎相同,但 jpg 总是小很多
    • 我希望我能选择两个答案。我接受了 Lou Franco 的另一个答案,因为他解释了 JPEG 压缩的一些问题。但我可能会使用此代码作为实现的起点,因为它不依赖外部 SDK。
    【解决方案2】:

    文件是否需要在内部为 JPEG 格式,或者只是名为 JPEG 的任意二进制文件?如果是后者,请参阅此 Stack Overflow 答案:

    Creating a Huge Dummy File in a Matter of Seconds in C#

    【讨论】:

    • +1 这也是我的第一个想法。只需创建您需要的确切大小的二进制文件并将它们命名为 .jpg
    • 不幸的是,出于我们实验的目的,我们正在尝试确定它们将如何通过电子邮件传输,我们预计某些格式可能会自动重新编码,而其他格式可能不会,所以我们希望它们是有效的内部格式。
    【解决方案3】:

    分辨率不会改变像素的数量,只会改变像素的显示大小——增加分辨率会使显示变大,但不会使文件变大。

    如果您制作的 JPEG 会一遍又一遍地重复相同的信息,它会变得更大——压缩是基于 8x8 单元格的——如果您有更多的单元格,您将拥有更多的数据。要使它们更大,请将质量设置为 100 进行编码。另外,JPEG 会以单元为单位去除亮度,因此色调变化比亮度变化压缩得更差。

    我使用我公司的产品DotImage 使用此代码创建了一个 10mb 的 jpg。您可以下载一个 eval 并尝试一下,或者对您的图像 SDK 执行相同的操作。

    using System;
    using System.Drawing;
    using Atalasoft.Imaging;
    using Atalasoft.Imaging.Codec;
    using Atalasoft.Imaging.Drawing;
    
    namespace MakeLargeImage
    {
        class Program
        {
            static void Main(string[] args)
            {
                AtalaImage img = new AtalaImage(1000, 8000, PixelFormat.Pixel24bppBgr);
                Canvas c = new Canvas(img);
    
                for (int block = 0; block < img.Height; block += 1000)
                {
                    for (int line = 0; line < 1000; line += 4)
                    {
                        int y = block + line;
                        c.DrawLine(new Point(0, y), new Point(img.Width, block), new AtalaPen(Color.Yellow));
                        c.DrawLine(new Point(0, y + 1), new Point(img.Width, y + 1), new AtalaPen(Color.Red));
                        c.DrawLine(new Point(0, y + 2), new Point(img.Width, y + 2), new AtalaPen(Color.Green));
                        c.DrawLine(new Point(0, block), new Point(img.Width, y + 3), new AtalaPen(Color.Blue));
                    }
                }
                JpegEncoder jpeg = new JpegEncoder(100);
                img.Save("10mb.jpg", jpeg, null);
            }
        }
    }
    

    如果您增大图像像素大小,JPEG 文件会变大。您也可以添加元数据,但很难获得仅包含元数据的大文件,因为存在一些大小限制。

    PDF 是最简单的——只需用未压缩的图像制作一个大页面并不断添加页面——它会很快变大——除非你打开它,否则没有压缩。您可以在 DotImage 中使用 PdfEncoder 轻松完成此操作——只需在 FileSystemImageSource 中给它一个 jpg 列表——代码未显示为不会让所有人感到厌烦,但我很乐意将它提供给任何想要的人它 - 只需致电 Atalasoft 并询问我(或打开支持案例并参考此问题。

    【讨论】:

    • 我希望我能选择两个答案。我选择了这个答案,因为您阐明了一些使这成为挑战的潜在过程。不过,我可能会使用 Nifle 的代码作为起点,并掌握这些信息。
    【解决方案4】:

    我会从所有这些格式的“巨大”文件开始(超过最大文件大小),然后使用 imagemagick convert 反复调整它们的大小,直到您找到所需文件大小的细节。

    可能需要一些试验和错误(虽然可以很容易地编写脚本),但应该进行一次性实验。

    【讨论】: