My goal is to draw some polygons on a black image such that the total size of the resulting image is as small as possible.
So I read an article on wiki about indexed colors (link) and it seems like it's a good choice for me (since I should support only a black color and the 5 other ones, i.e. 6 colors in total) and png
image format should support 'P' mode (i.e., palette images).
That's the reason I created this piece of code to see what image size I'll get for 6 colors and 1224x1024
image:
from PIL import Image, ImageDraw
# Create a black 1224x1024 image
img = Image.new('P', (1224, 1024))
img.putpalette([
0, 0, 0, # black background
236, 98, 98, # red color
236, 98, 97,
236, 98, 96,
236, 98, 95,
236, 98, 94,
])
draw = ImageDraw.Draw(img)
# Draw a random red polygon at the top left corner of the image
draw.polygon(xy=list(1,1,2,2,3,3,4,4), fill=1)
del draw
img.save('1.png', format='PNG')
The result image size is 768
bytes which seems too much for me.
Is there something I can fix in my code to make the result image size even smaller?
768 bytes does not seem unreasonable to me to represent a 1.2 megapixel image. You could try running the file produced by PIL through
pngcrush
like this to see if it can shave a few bytes:If you really only want to draw a few solid-coloured polygons on a black background, I would suggest you look to a vector format, such as SVG example here rather than raster format PNG et al.
You can also use rsvg to render SVG images to PNG if you need to but neither your application, nor the reason you need such small images is clear from your question, so I have no idea if that is an option for you.
Here is a 300 byte SVG image with a black background, 2 rectangles and a polygon like a red star shape at top-left:
You could load an SVG into a Numpy array like this:
If you are hell-bent on making the files even smaller, at the price of reduced compatibility with other image viewers, you could devise your own very simple format somewhat similar to SVG, so you could store the image represented by the SVG example I gave as a simple text file:
And I make that 127 bytes.
You can view your SVG files by loading them into any web-browser, or make one into a PNG with ImageMagick in Terminal like this: