diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon
index 037ee997..b209e822 100644
--- a/phpstan-baseline.neon
+++ b/phpstan-baseline.neon
@@ -5920,16 +5920,6 @@ parameters:
count: 1
path: src/PhpSpreadsheet/Worksheet/Iterator.php
- -
- message: "#^Parameter \\#1 \\$im of function imagesx expects resource, GdImage\\|resource given\\.$#"
- count: 1
- path: src/PhpSpreadsheet/Worksheet/MemoryDrawing.php
-
- -
- message: "#^Parameter \\#1 \\$im of function imagesy expects resource, GdImage\\|resource given\\.$#"
- count: 1
- path: src/PhpSpreadsheet/Worksheet/MemoryDrawing.php
-
-
message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\PageSetup\\:\\:\\$pageOrder has no typehint specified\\.$#"
count: 1
diff --git a/phpstan.neon.dist b/phpstan.neon.dist
index dd39aa34..b7a4fca8 100644
--- a/phpstan.neon.dist
+++ b/phpstan.neon.dist
@@ -16,6 +16,8 @@ parameters:
- '~^Return typehint of method .* has invalid type GdImage\.$~'
- '~^Property .* has unknown class GdImage as its type\.$~'
- '~^Parameter .* of method .* has invalid typehint type GdImage\.$~'
+ - '~^Parameter \#1 \$im of function (imagedestroy|imageistruecolor|imagealphablending|imagesavealpha|imagecolortransparent|imagecolorsforindex|imagesavealpha|imagesx|imagesy) expects resource, GdImage\|resource given\.$~'
+ - '~^Parameter \#2 \$src_im of function imagecopy expects resource, GdImage\|resource given\.$~'
# Accept a bit anything for assert methods
- '~^Parameter \#2 .* of static method PHPUnit\\Framework\\Assert\:\:assert\w+\(\) expects .*, .* given\.$~'
- '~^Method PhpOffice\\PhpSpreadsheetTests\\.*\:\:test.*\(\) has parameter \$args with no typehint specified\.$~'
diff --git a/src/PhpSpreadsheet/Worksheet/MemoryDrawing.php b/src/PhpSpreadsheet/Worksheet/MemoryDrawing.php
index cde23c96..7789543a 100644
--- a/src/PhpSpreadsheet/Worksheet/MemoryDrawing.php
+++ b/src/PhpSpreadsheet/Worksheet/MemoryDrawing.php
@@ -3,6 +3,7 @@
namespace PhpOffice\PhpSpreadsheet\Worksheet;
use GdImage;
+use PhpOffice\PhpSpreadsheet\Exception;
class MemoryDrawing extends BaseDrawing
{
@@ -21,7 +22,7 @@ class MemoryDrawing extends BaseDrawing
/**
* Image resource.
*
- * @var GdImage|resource
+ * @var null|GdImage|resource
*/
private $imageResource;
@@ -60,10 +61,71 @@ class MemoryDrawing extends BaseDrawing
parent::__construct();
}
+ public function __destruct()
+ {
+ if ($this->imageResource) {
+ imagedestroy($this->imageResource);
+ $this->imageResource = null;
+ }
+ }
+
+ public function __clone()
+ {
+ parent::__clone();
+ $this->cloneResource();
+ }
+
+ private function cloneResource(): void
+ {
+ if (!$this->imageResource) {
+ return;
+ }
+
+ $width = imagesx($this->imageResource);
+ $height = imagesy($this->imageResource);
+
+ if (imageistruecolor($this->imageResource)) {
+ $clone = imagecreatetruecolor($width, $height);
+ if (!$clone) {
+ throw new Exception('Could not clone image resource');
+ }
+
+ imagealphablending($clone, false);
+ imagesavealpha($clone, true);
+ } else {
+ $clone = imagecreate($width, $height);
+ if (!$clone) {
+ throw new Exception('Could not clone image resource');
+ }
+
+ // If the image has transparency...
+ $transparent = imagecolortransparent($this->imageResource);
+ if ($transparent >= 0) {
+ $rgb = imagecolorsforindex($this->imageResource, $transparent);
+ if ($rgb === false) {
+ throw new Exception('Could not get image colors');
+ }
+
+ imagesavealpha($clone, true);
+ $color = imagecolorallocatealpha($clone, $rgb['red'], $rgb['green'], $rgb['blue'], $rgb['alpha']);
+ if ($color === false) {
+ throw new Exception('Could not get image alpha color');
+ }
+
+ imagefill($clone, 0, 0, $color);
+ }
+ }
+
+ //Create the Clone!!
+ imagecopy($clone, $this->imageResource, 0, 0, 0, 0, $width, $height);
+
+ $this->imageResource = $clone;
+ }
+
/**
* Get image resource.
*
- * @return GdImage|resource
+ * @return null|GdImage|resource
*/
public function getImageResource()
{
diff --git a/src/PhpSpreadsheet/Writer/Html.php b/src/PhpSpreadsheet/Writer/Html.php
index 4ee94114..b694d4ef 100644
--- a/src/PhpSpreadsheet/Writer/Html.php
+++ b/src/PhpSpreadsheet/Writer/Html.php
@@ -690,18 +690,21 @@ class Html extends BaseWriter
$drawing->getWidth() . 'px; height: ' . $drawing->getHeight() . 'px;" src="' .
$imageData . '" alt="' . $filedesc . '" />';
} elseif ($drawing instanceof MemoryDrawing) {
- ob_start(); // Let's start output buffering.
- imagepng($drawing->getImageResource()); // This will normally output the image, but because of ob_start(), it won't.
- $contents = ob_get_contents(); // Instead, output above is saved to $contents
- ob_end_clean(); // End the output buffer.
+ $imageResource = $drawing->getImageResource();
+ if ($imageResource) {
+ ob_start(); // Let's start output buffering.
+ imagepng($imageResource); // This will normally output the image, but because of ob_start(), it won't.
+ $contents = ob_get_contents(); // Instead, output above is saved to $contents
+ ob_end_clean(); // End the output buffer.
- $dataUri = 'data:image/jpeg;base64,' . base64_encode($contents);
+ $dataUri = 'data:image/jpeg;base64,' . base64_encode($contents);
- // Because of the nature of tables, width is more important than height.
- // max-width: 100% ensures that image doesnt overflow containing cell
- // width: X sets width of supplied image.
- // As a result, images bigger than cell will be contained and images smaller will not get stretched
- $html .= '
';
+ // Because of the nature of tables, width is more important than height.
+ // max-width: 100% ensures that image doesnt overflow containing cell
+ // width: X sets width of supplied image.
+ // As a result, images bigger than cell will be contained and images smaller will not get stretched
+ $html .= '
';
+ }
}
}