I'm trying to compress uploaded images down to a specific size of 200Kb. I don't want to compress them any more than they need to be and using lossless compression like PNG isn't enough. Simply setting it to imagejpeg($image, null, 40)
creates different compressed sizes for different images. Is there a way to set the desired compression size in bytes or at least have some algorithm that can find out the compression output without looping through imagejpeg()
from 100 to 0 quality?
Asked
Active
Viewed 505 times
0

user9391457
- 21
- 3
-
You don't need to loop through all sizes from 100 to 0, you can use a binary search like this... https://stackoverflow.com/a/52281257/2836621 – Mark Setchell Jul 14 '19 at 21:27
-
Or you can *"shell out"* to **ImageMagick** and do this... https://stackoverflow.com/a/29549024/2836621 – Mark Setchell Jul 14 '19 at 21:29
-
You can probably use Imagick (the PHP binding to ImageMagick) and then use `$imagick->setOption('jpeg:extent', 200000);` – Mark Setchell Jul 14 '19 at 22:19
2 Answers
1
I found a way to use ob to view the file size of the image before it is uploaded so I used it in a loop
// Get get new image data
ob_start();
// Build image with minimal campression
imagejpeg($newImage, NULL, 100);
// Get the size of the image file in bytes
$size = ob_get_length();
// Save new image into a variable
$compressedImage = addslashes(ob_get_contents());
// Clear memory
ob_end_clean();
// If image is larger than 200Kb
if ($size > 200000) {
// This variable will decrease by 2 every loop to try most combinations
// from least compressed to most compressed
$compressionValue = 100;
for ($i=0; $i < 50; $i++) {
$compressionValue = $compressionValue - 2;
ob_start();
imagejpeg($newImage, NULL, $compressionValue);
$size = ob_get_length();
// Overwrite old compressed image with the new compressed image
$compressedImage = addslashes(ob_get_contents());
// Clear memory
ob_end_clean();
// If image is less than or equal to 200.5Kb stop the loop
if ($size <= 200500) {
break;
}
}
}
This is incredibly well optimized on its own too. The whole process only takes a few milliseconds with a 1.5Mb starting image even when it is trying 50 combinations.

user9391457
- 21
- 3
0
There really isn't any way to predict the level of compression beforehand. The effect of compression depends upon the image source. One of the problems is that there is a myriad of JPEG compression settings.
- The quantization tables (up to 3) with 64 different values.
- Sub sampling.
- Spectral selection in progressive scans.
- Successive Approximation in progressive scans.
- Optimize huffman tables.
So there are billions upon billions of parameters that you can set.
There are JPEG optimization applications out there that will look at the compressed data.

user3344003
- 20,574
- 3
- 26
- 62