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
View Add Comment Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
You can add a comment by following this link or if you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: marc at gutt dot it
New email:
PHP Version: OS:

 

 [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

Add a Patch

Pull Requests

Add a Pull Request

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: Sun May 19 11:01:37 2024 UTC