// fix PNG alpha channel handling
// see http://php.net/manual/en/function.imagecopymerge.php#92787
$cut = imagecreatetruecolor($overlayImage->getWidth(), $overlayImage->getHeight());
+ imagealphablending($cut, false);
+ imagesavealpha($cut, true);
+
imagecopy($cut, $this->image, 0, 0, $x, $y, $overlayImage->getWidth(), $overlayImage->getHeight());
imagecopy($cut, $overlayImage->image, 0, 0, 0, 0, $overlayImage->getWidth(), $overlayImage->getHeight());
- imagecopymerge($this->image, $cut, $x, $y, 0, 0, $overlayImage->getWidth(), $overlayImage->getHeight(), $opacity * 100);
+
+ $this->imagecopymerge_alpha($this->image, $cut, $x, $y, 0, 0, $overlayImage->getWidth(), $overlayImage->getHeight(), $opacity * 100);
+ }
+
+ /**
+ * `imagecopymerge` implementation with alpha support.
+ *
+ * @see http://php.net/manual/en/function.imagecopymerge.php#88456
+ *
+ * @param resource $dst_im destination image resource
+ * @param resource $src_im source image resource
+ * @param integer $dst_x x-coordinate of destination point
+ * @param integer $dst_y y-coordinate of destination point
+ * @param integer $src_x x-coordinate of source point
+ * @param integer $src_y y-coordinate of source point
+ * @param integer $src_w source width
+ * @param integer $src_h source height
+ * @param integer $pct opacity percent
+ * @return boolean
+ */
+ private function imagecopymerge_alpha($dst_im, $src_im, $dst_x, $dst_y, $src_x, $src_y, $src_w, $src_h, $pct) {
+ if (!isset($pct)) {
+ return false;
+ }
+ $pct /= 100;
+ // Get image width and height
+ $w = imagesx($src_im);
+ $h = imagesy($src_im);
+ // Turn alpha blending off
+ imagealphablending($src_im, false);
+ // Find the most opaque pixel in the image (the one with the smallest alpha value)
+ $minalpha = 127;
+ for ($x = 0; $x < $w; $x++) {
+ for ($y = 0; $y < $h; $y++) {
+ $alpha = (imagecolorat($src_im, $x, $y) >> 24) & 0xFF;
+ if ($alpha < $minalpha) {
+ $minalpha = $alpha;
+ }
+ }
+ }
+ // loop through image pixels and modify alpha for each
+ for ($x = 0; $x < $w; $x++) {
+ for ($y = 0; $y < $h; $y++) {
+ // get current alpha value (represents the TANSPARENCY!)
+ $colorxy = imagecolorat($src_im, $x, $y);
+ $alpha = ($colorxy >> 24) & 0xFF;
+ // calculate new alpha
+ if ($minalpha !== 127) {
+ $alpha = 127 + 127 * $pct * ($alpha - 127) / (127 - $minalpha);
+ }
+ else {
+ $alpha += 127 * $pct;
+ }
+ // get the color index with new alpha
+ $alphacolorxy = imagecolorallocatealpha($src_im, ($colorxy >> 16) & 0xFF, ($colorxy >> 8) & 0xFF, $colorxy & 0xFF, $alpha);
+ // set pixel with the new color + opacity
+ if (!imagesetpixel($src_im, $x, $y, $alphacolorxy)) {
+ return false;
+ }
+ }
+ }
+ // The image copy
+ imagecopy($dst_im, $src_im, $dst_x, $dst_y, $src_x, $src_y, $src_w, $src_h);
+
+ return true;
}
/**