5

I am doing image manipulation on the png images. I have the following problem. After saving an image with imwrite() function, the size of the image is increased. For example previously image is 847KB, after saving it becomes 1.20 MB. Here is a code. I just read an image and then save it, but the size is increased. I tried to set compression params but it doesn't help.

Mat image;
image = imread("5.png", -1); 

vector<int> compression_params;
compression_params.push_back(CV_IMWRITE_PNG_COMPRESSION);
compression_params.push_back(9);
compression_params.push_back(0);

imwrite("output.png",image,compression_params);

What could be a problem? Any help please. Thanks.

Karmar
  • 570
  • 1
  • 6
  • 15
  • 1
    I have the same issue and I guess it depends on the libraries used to compress the original image and the png library used by OpenCV. – Jav_Rock Dec 04 '12 at 14:34
  • what is -1 in imread? Why don't you just use imread("5.png")? – Barney Szabolcs Dec 06 '12 at 09:26
  • when setting second parameter to -1, imread will read png transparent image, otherwise it will not return alpha channel of the png image – Karmar Dec 06 '12 at 11:11

2 Answers2

5

PNG has several options that influence the compression: deflate compression level (0-9), deflate strategy (HUFFMAN/FILTERED), and the choice (or strategy for dynamically chosing) for the internal prediction error filter (AVERAGE, PAETH...). It seems OpenCV only lets you change the first one, and it hasn't a good default value for the second. So, it seems you must live with that.

Update: looking into the sources, it seems that compression strategy setting has been added (after complaints), but it isn't documented. I wonder if that source is released. Try to set the option CV_IMWRITE_PNG_STRATEGY with Z_FILTERED and see what happens

See the linked source code for more details about the params.

Ciprian Tomoiagă
  • 3,773
  • 4
  • 41
  • 65
leonbloy
  • 73,180
  • 20
  • 142
  • 190
  • So there is no solution for this problem with OpenCV? – Karmar Dec 04 '12 at 14:51
  • You mean setting CV_IMWRITE_PNG_STRATEGY_FILTERED option? I write compression_params.push_back(CV_IMWRITE_PNG_STRATEGY_FILTERED); compression_params.push_back(9); but nothing happens. – Karmar Dec 04 '12 at 15:28
  • I tried CV_IMWRITE_PNG_STRATEGY with Z_FILTERED. It decreases the size, but very little. For 1.20MB image I get 1.12MB – Karmar Dec 04 '12 at 15:47
1

@Karmar, It's been many years since your last edit.

I had similar confuse to yours in June, 2021. And I found out sth which might benefit others like us.

PNG files seem to have this thing called mode. Here, let's focus only on three modes: RGB, P and L. To quickly check an image's mode, you can use Python:

from PIL import Image
print(Image.open("5.png").mode)

Basically, when using P and L you are attributing 8 bits/pixel while RGB uses 3*8 bits/pixel. For more detailed explanation, one can refer to this fine stackoverflow post: What is the difference between images in 'P' and 'L' mode in PIL?

Now, when we use OpenCV to open a PNG file, what we get will be an array of three channels, regardless which mode that file was saved into. Three channels with data type uint8, that means when we imwrite this array into a file, no matter how hard you compress it, it will be hard to beat the original file if it was saved in P or L mode.

I guess @Karmar might have already had this question solved. For future readers, check the mode of your own 5.png.

phunc20
  • 11
  • 1
  • 3
  • This question was posted 8 years ago. You are also using the `Python Imaging Library (PIL)` not `OpenCV`. Furthermore, this question and previous answers use the `C++` implementation of `OpenCV`, where `PIL` is obviously not available (at least not "natively"), so I'm not sure if your answer is still relevant. – stateMachine Jun 10 '21 at 02:19
  • If you read closely, you will find what I spent time writing makes sense. I am not using `PIL` to solve the problem; I am using it to quickly get to know what image mode is. – phunc20 Jun 10 '21 at 03:37
  • I am less familiar with `C++`, but I am almost sure that there exist libraries in `C++` to check image mode as well. – phunc20 Jun 10 '21 at 03:46
  • This is an excellent point. You can read about the PNG modes in [this other Q&A](https://stackoverflow.com/q/52307290/7328782). – Cris Luengo Jun 10 '21 at 12:53