I am trying to rotate some images whose width is more than height about the left-top corner, by 90 degrees. I have written this :
from PIL import Image
import sys, csv, os, traceback, glob
import shutil, math
src_im = Image.open("Test.png")
print src_im.size[0] , ',' , src_im.size[1]
src_im = src_im.transpose(Image.ROTATE_90)
src_im = src_im.transpose(Image.FLIP_LEFT_RIGHT)
src_im = src_im.transpose(Image.FLIP_TOP_BOTTOM)
src_im.save("TestResult.png")
print src_im.size[0] , ',' , src_im.size[1]
Output generated is as I expect, but there is a huge change in size. Any ideas where I might be going wrong ?
Its the same pixel information being stored, just rotated, why should there be a change in the image size ?
(312 x 936) 342KB
Edit:
Ok, so I tried rotating the images with the inbuilt image viewer of windows, and there is an increase in that case as well. So its not really specific to Python per se. More about compression. Am still not clear why would it be less compressible on rotation ? And this is happening for all images I am trying, not this particular one. Updating the tags accordingly.
PNG compress the image by "filtering" each line, trying to predict the values for each pixel as a function of the "past" neighbours (previous row and/or column), and then compressing the prediction error by using ZLIB (Deflate). The issue here seems to be this: the vertical image has almost vertical stripes; when scanned along the rows, it has a fairly predictable medium-range pattern (about 8 similar colors followed by a short burst of lighter colour). This suggest that, while the short-range prediction will not be very successful, the prediction error will get a highly repetitive pattern, that should be relatively easy to compress. This does not happen when the image is rotated.
I verified that the different horizontal/vertical sizes were not the problem: I made a bigger square (900x900) by repeating the original image 9 times. The PNG image with quasi vertical stripes has roughly half the size than the other one.
Another experiment that confirms the above: save both images as grayscale BMP (this is an uncompressed format, it stores one byte per pixel, along the rows). You get two images of 293.110 bytes. Compress both of them with a standard ZIP compressor (same family as ZLIB's deflate). The vertical image, again, gets about half the size than the other one.