Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ language: php
php:
- 7.2
- 7.3
- 7.4
- 8.0
install:
- composer install --no-interaction
script:
Expand Down
38 changes: 27 additions & 11 deletions src/GDImage.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,36 +14,52 @@ class GDImage
* Constructs a new instance. Accepts either an image resource or a file
* path to load the image from.
*
* @param string|resource $value The image resource or file path.
* If you provide an already-loaded image resource, it is YOUR job to
* destroy the image when you no longer need it.
* Resources loaded from a file will be destroyed by this class upon calling
* finish().
*
* @param string|resource|\GdImage $value The image resource or file path.
*/
public function __construct($value)
{
if (!is_resource($value)) {
$value = imagecreatefromstring(file_get_contents($value));
$this->destroy = true;
// PHP < 8 uses resources, PHP >= 8 uses GdImage objects.
if (is_resource($value) || $value instanceof \GdImage) {
$this->res = $value;
return;
}
$this->res = $value;
$this->res = imagecreatefromstring(file_get_contents($value));
$this->destroy = true;
}

/**
* @return resource The underlying GD image resource.
* Disposes of this image by calling `finish()`.
*/
public function getResource()
public function __destruct()
{
return $this->res;
$this->finish();
}

/**
* Frees the allocated resource if it was loaded in the constructor. Will
* not free the resource if it was passed already-loaded.
* Free any allocated resources. This should be called as soon as the image
* is no longer needed.
*
* @return void
*/
public function finish()
{
if ($this->destroy) {
if ($this->destroy && isset($this->res)) {
imagedestroy($this->res);
}
$this->res = null;
}

/**
* @return resource The underlying GD image resource.
*/
public function getResource()
{
return $this->res;
}

/**
Expand Down
16 changes: 11 additions & 5 deletions tests/GDImageTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,17 @@ public function testFinish()
$obj = new GDImage('./tests/images/stripes-bw-10x10.png');
$img = $obj->getResource();
$obj->finish();
try {
imagesx($img);
} catch (Exception $e) {
return;
// skip on PHP >= 8, where images are objects instead of resources
// and where manual destruction does nothing
if (is_resource($img)) {
// expect resource to be destroyed
try {
imagesx($img);
} catch (Exception $e) {
return;
}
$this->fail();
}
$this->fail();
$this->assertNull($obj->getResource());
}
}