difference in file-size when using share_image_data(bytesObj) vs. write(bytesObj)
I'm having a weird issue when trying to save a PIL image to disk.
Using the same input data with 2 different save methods, I'm getting significantly different file sizes for the resulting file-on-disk. In the case of very large images (4000px wide), the difference can be as much as 4 MB!
The process I'm using is exactly the same as the one used in dialogs.share_image_data():
fileRepr_temp = io.BytesIO() # create stream to in-memory resource pilImg.save(fileRepr_temp, 'PNG' ) img_data = fileRepr_temp.getvalue() # get a bytes obj
# save to disk using iOS (rstr, rlist) = dialogs.share_image_data(img_data)
# save to disk by writing bytes obj to file fileRepr = open(pathStr, mode='wb') fileRepr.seek(0) fileRepr.write(img_data) fileRepr.close()
For some reason, the file saved through iOS is significantly smaller than the one created using write(). I'd like to be able to write this same smaller file-size without having to call the iOS dialogue (this is part of a batch-processing script).
Unfortunately I don't know enough about file IO to understand what's going on here. :(
Any help would be appreciated!
If I'm not completely wrong, the first variant saves image data in PNG format while the "write" version seems to use raw image data, hence the difference in size. PNG is compressed, the latter is uncompressed.
Png is generally uncompressed. You could use jpg instead, which will be both faster and smaller, though with jpeg artifacts, which may or may not matter depending on what you are saving
I thought the whole goal of PNG was to move to lossless compression that was free of legal constraints https://en.wikipedia.org/wiki/Portable_Network_Graphics#Compression
Png is lossless compressed (or, can be).
But jpg is MUCH smaller, in that it is losdy compression, and also much faster to convert.
@tomoto-sauce, I simulated what
share_image_datamight be doing and converted the PIL to an ui.Image (UIImage) before saving (#3, below).
The results... The file sizes of #1 and #3 are the same, and all are PNGs, but in the case of my image, their size was almost 16 MB while the plain byte dump in #2 was about 11 MB. This sounds like the reverse of what you found.
import io import dialogs import photos import ui pil = photos.get_assets()[-1].get_image() with io.BytesIO() as tmp: pil.save(tmp, 'PNG') img_data = tmp.getvalue() # 1 dialogs.share_image_data(img_data) # 2 with open('experiment2.png', mode='wb') as fp: fp.write(img_data) # 3 img = ui.Image.from_data(img_data) with open('experiment3.png', mode='wb') as fp: fp.write(img.to_png())