2

Im trying to make image compressor in my django project. I did well with jpg, but got a lot of problems with png. For compression i using PIL and cv2, but cant get result better then 16% of compression for big PNG files (>1 mb). Ive tryed to combine both libraries, and its still not innove. Here simple code of my view:

(the above code for jpg compression)

elif picture.mode == ('RGBA'):
            if photo.image.size < 1000000:
                colorsloss = picture.convert(mode="P", palette=Image.ADAPTIVE)
                colorsloss.save('media/new/'+name,"PNG",quality=75, optimize=True, bits=8)
            else:
                originalImage = cv.imread(str('/home/andrey/sjimalka'+ photo.image.url))
                cv.imwrite('media/new/'+name, originalImage,[cv.IMWRITE_PNG_COMPRESSION, 9])
                cvcompressed = Image.open('media/new/'+name)
                cvcompressed.convert(mode="RGB")
                cvcompressed.save('media/new/'+name,"PNG",quality=75, optimize=True)

So here ive got 2 big problems: 1) If ive got low size image (< 1 mb), i using P mode in Pillow. It works great, but if i compressing image with gradient, i can see some distortions in places where i got gradient. original compressed I have good compression (something like 85%), but no idea yet how to fix it.

2) I cant get good compression of big png files. My best goal yet is 16%, with really good quality, but it still not innove. Mb i do something wrong, or i shold use any other library or technology to make it better. I want to get a list 50% of compression with big png files.

I already tryed to use pngquant, but their docs wasnt too clear for me, and i cant find good code examples.

Andrej Vilenskij
  • 487
  • 1
  • 7
  • 23

1 Answers1

1

PNG is lossless. You cannot choose to discard information when writing in order to make files smaller like you can with JPEG.

If you go for a palettised version, you only need one byte per pixel instead of three, but then you only get 256 colours and gradients will look rubbish.

Also, the quality setting is not the same as for JPEG - it is more like the --fast or --best parameter to gzip.

One thing you can do, if you have large areas of transparency like you do, is make black all pixels that are 100% transparent. That will help them compress better. See example here.

Mark Setchell
  • 191,897
  • 31
  • 273
  • 432
  • Thx for your answer. I found another one library called PyPNG. Right now i want to decompose png pic by pixels, and try to make some manipulations with pixel arrays. Probably if i programmatically draw a picture based on the incoming one, size will be less. Im not sure that it could work, but right now i see it like a best way achieve the desired. – Andrej Vilenskij Oct 03 '18 at 10:04