Search code examples
imagesvgpnggifimage-compression

What's the smallest image format for randomly sized uniformly coloured images?


Without going into much detail, I'm trying to do an HTTP POST of a dummy image to a server to cause the server to create an internal record of the image in its database. The image is to later be replaced in storage with the actual image that's supposed to be there without the server knowing.

Unfortunately, this server is "smart" and validates whatever image data is being sent to it; it will reject random bytes if they don't match some image format (e.g. jpeg, gif, png. etc).

Naturally, the most obvious approach would be to send the smallest gif possible (1x1 grey pixel; ~26 bytes). Unfortunately, this server keeps an immutable record of the dimensions of the image that it reads... so a 1x1 pixel image won't cut it.

So my question is, what's the smallest possible scaled image of a solid colour I can send as a dummy instead? Ideally, a completely uniformly grey image of 100x100 pixels in this format should be roughly the same as a 1000x2000 image of the same colour, due to compression.

(Forgive me if the tags aren't very good; I'm not sure where this should go)


Solution

  • You can possibly achieve what you want with a specially-crafted GIF file.

    The GIF format allows you to specify "logical screen width" and "logical screen height" values in the "Logical Screen Descriptor" section at the start of the file, which define the size of the image.

    However, you don't actually need to encode the pixels for the entire image, and any pixels which are not encoded are considered transparent. Instead, the GIF file contains one or more "Image Descriptor" sections, which encodes the pixels for a sub-region of the image. This is used for compressing GIF animations (only the sub-regions of the image that change compared to the previous frame need to be encoded) but it can also be used for single-frame images. So what you can do is just output a single Image Descriptor encoding a 1x1 transparent pixel region of the image, and set the logical screen width and height values your desired image size, to create a uniformly transparent GIF image of arbitrary size, for a fixed file size (42 bytes).

    You just need to modify bytes 6-9 (for the width) and bytes 10-13 (for the height) of this transparent 1x1 pixel GIF. Note that GIF uses little-endian byte order.

    Here is an example file, a 1024 x 1024 pixel transparent GIF image.

    This file loads up correctly for me as a 1k by 1k transparent image in the GIMP image editor, but some file viewers seem to base the image size on the size of the image descriptors and display it as 1x1 pixels, which is wrong AFAIK. You'll have to test whether your server reads them correctly.