Bug #75382 [Opn->Nab]: imagerotate() doubles the memory usage

From: Date: Sun, 15 Oct 2017 15:07:57 +0000
Subject: Bug #75382 [Opn->Nab]: imagerotate() doubles the memory usage
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-211700@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=75382&edit=1 ID: 75382 Updated by: requinix@php.net Reported by: marc at gutt dot it Summary: imagerotate() doubles the memory usage -Status: Open +Status: Not a bug Type: Bug Package: *Graphics related PHP Version: 5.6.31 Block user comment: N Private report: N New Comment: When rotating by 180 degrees, sure GD could overwrite - it's just a flip, and flipping in place is easy: flip each pair of pixels at the same time. Rotating by 90 or 270 degrees in place is also possible using a similar approach of flipping each set of four pixels at the same time. But unless there's some fancy and efficient technique I don't know of (I would be pleasantly surprised) any other rotation requires mapping multiple input pixels to one output pixel by inspecting neighboring pixels that have not been moved yet, thus preventing the use of the in-place flipping technique. Non-trivial image processing takes memory. Can't just wish that away. But regardless of all that, GD does not support such a feature so PHP cannot either. You'd have to ask them for it first. https://github.com/libgd/libgd/issues Previous Comments: ------------------------------------------------------------------------ [2017-10-15 13:27:00] marc at gutt dot it Description: ------------ imagerotate() doubles the memory usage instead of functions like imageflip(). Its not really a bug because the function returns a new image resource but as image resolutions grow year-by-year this increases the memory requirements, too. I think the function should not return a new resource. Instead it should be a added a 4th option to overwrite the original image resource: imagerotate ( resource $image , float $angle , int $bgd_color [, int $ignore_transparent = 0 [, bool $return = true ]] ) Test script: --------------- <?php // image $url = 'https://upload.wikimedia.org/wikipedia/commons/thumb/a/a7/Pluto-01_Stern_03_Pluto_Color_TXT.jpg/1024px-Pluto-01_Stern_03_Pluto_Color_TXT.jpg'; file_put_contents('../cache4/' . basename($url), fopen($url, 'r')); $filename = '../cache4/' . basename($url); echo 'Before imagecreate: ' . round(memory_get_usage() / pow(1024, 2)) . ' MB (Max: ' . round(memory_get_peak_usage() / pow(1024, 2)) . ' MB)<br>' . PHP_EOL; // create image resource $image = imagecreatefromjpeg($filename); echo 'After imagecreate: ' . round(memory_get_usage() / pow(1024, 2)) . ' MB (Max: ' . round(memory_get_peak_usage() / pow(1024, 2)) . ' MB)<br>' . PHP_EOL; // rotate image $image = imagerotate($image, 180, 0); echo 'After imagerotate: ' . round(memory_get_usage() / pow(1024, 2)) . ' MB (Max: ' . round(memory_get_peak_usage() / pow(1024, 2)) . ' MB)<br>' . PHP_EOL; ?> Expected result: ---------------- Before imagecreate: 0 MB (Max: 0 MB) After imagecreate: 5 MB (Max: 5 MB) After imagerotate: 5 MB (Max: 5 MB) (by using "imagerotate($image, 180, 0, 0, false);") Actual result: -------------- Before imagecreate: 0 MB (Max: 0 MB) After imagecreate: 5 MB (Max: 5 MB) After imagerotate: 5 MB (Max: 10 MB) ------------------------------------------------------------------------ -- Edit this bug report at https://bugs.php.net/bug.php?id=75382&edit=1

« previous php.bugs (#211700) next »