php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #75382 imagerotate() doubles the memory usage
Submitted: 2017-10-15 13:27 UTC Modified: 2017-10-15 15:07 UTC
From: marc at gutt dot it Assigned:
Status: Not a bug Package: *Graphics related
PHP Version: 5.6.31 OS:
Private report: No CVE-ID: None
 [2017-10-15 13:27 UTC] 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)

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2017-10-15 15:07 UTC] requinix@php.net
-Status: Open +Status: Not a bug
 [2017-10-15 15:07 UTC] requinix@php.net
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
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Wed Dec 04 19:01:32 2024 UTC