Reputation: 390
For a network experiment I am conducting, I require image files of arbitrary size.
I am lost on how to create such files. I require 5MB, 10MB and 20MB files in JPEG, PNG and PDF format.
In my first attempt at generating these files it became clear that due to the compression schemes of these formats, it's not possible (or at least I don't know how) to generate files of arbitrary size by just specifying resolution of blank files.
Is there a quick (programmatic?) method by which I could generate these files?
Edit: I am investigating creating arbitrarily sized dummy files, but if there is a way to create actual JPEG, PNGs or PDFs that have the correct internal format, that would be ideal.
Upvotes: 5
Views: 9696
Reputation: 16930
You can use the 'fallocate' linux utility part of linux-utils:
For example. To let's sya you have an image of size 200KB and you want it to have the size 260KB without changing the image. You can just do this:
fallocate -l 260KB image.jpg
This works on JPEG files (and others) because most image formats ignore trailing zeros, and can be appended to, without affecting the image.
Upvotes: -1
Reputation: 89192
The resolution doesn't change the number of pixels, just the display size of a pixel -- increasing resolution makes the display larger, but doesn't make the file larger.
If you make a JPEG that repeats the same information over and over again it will get bigger -- the compression is on a 8x8 cell basis -- if you have more cells, you'll have more data. To make them bigger, encode with quality set to 100. Another thing, JPEG strips out luminance on a cell basis, so variation in hue compresses worse than variation in luminance.
I used my company's product, DotImage, to create a 10mb jpg with this code. You could download an eval and try it out, or do the same with your image 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);
}
}
}
If you make the image pixel size larger, the JPEG file will get larger. You could also add in meta-data, but it's hard to get a big file with just meta-data as there are some size limitations.
PDF is the easiest -- just make a big page with uncompressed image and keep adding pages -- it will get big fast -- there's no compression unless you turn it on. You can do this easily in DotImage with the PdfEncoder
-- just give it a list of jpgs in a FileSystemImageSource
-- code not shown as to not bore everyone, but I'd be happy to provide it to anyone that wants it -- just call Atalasoft and ask for me (or open a support case and reference this question.
Upvotes: 2
Reputation: 11923
This is just a suggestion. No idea if it will work.
Perhaps you could generate bitmaps at the correct size and convert them?
If you make the bitmaps very hard to compress(1)? You should then be able to convert them to jpg and png very close to the target size.
(1) My suggestion is that this might be achieved by making each pixel in the bitmap a different colour (as far as possible)
Edit:
This simple solution probably does not work for jpg's, but at least png's seems to work.
I hacked together a small testapp in c# to try it out. Here is the meat of it:
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();
}
Upvotes: 4
Reputation: 116187
I would start with a 'huge' file in all of these formats (over max. filesize) and then iteratively resize them using imagemagick convert until you found the specifics for your wanted filesize.
May take some trial and error (can easily be scripted though) but should do for a one-time experiment.
Upvotes: 2
Reputation: 72870
Do the files need to be JPEG format internally, or just arbitrary binary files named JPEG? If the latter, see this Stack Overflow answer:
Creating a Huge Dummy File in a Matter of Seconds in C#
Upvotes: 2