Some PNG gets black background instead of transparent
Posted: 2015-02-11T08:50:18-07:00
I'm using ImageMagick 6.6.5-9 2010-11-15 Q16
with PHP module 3.1.2 (php_imagick-3.1.2-5.3-nts-vc9-x86.zip)
I'm having a bunch of PNG-logotypes which i wan't to scale down to a certain fixed size.
Two of them always gets a black background when resized (allthough original PNG are transparent).
GD-library which i replaced with Imagick could handle this by converting the logotypes to truecolor when reading them.
I have tried the following:
1. Resave the original which failed in Photoshop using PNG24 with a new filename (this is not a solution anyway in my case since i have no control of what the user uploads)..however it did no difference
2. Various other methods like adding $image->setFormat('png24')
This is the specific function:
This is the whole Image class which i've built:
with PHP module 3.1.2 (php_imagick-3.1.2-5.3-nts-vc9-x86.zip)
I'm having a bunch of PNG-logotypes which i wan't to scale down to a certain fixed size.
Two of them always gets a black background when resized (allthough original PNG are transparent).
GD-library which i replaced with Imagick could handle this by converting the logotypes to truecolor when reading them.
I have tried the following:
1. Resave the original which failed in Photoshop using PNG24 with a new filename (this is not a solution anyway in my case since i have no control of what the user uploads)..however it did no difference
2. Various other methods like adding $image->setFormat('png24')
This is the specific function:
Code: Select all
public function resize($width = 0, $height = 0, $default = '', $method = 'THUMB', $filter = Imagick::FILTER_CATROM) {
if (!$this->info['width'] || !$this->info['height']) {
return;
}
$xpos = 0;
$ypos = 0;
$scale = 1;
$scale_w = $width / $this->info['width'];
$scale_h = $height / $this->info['height'];
if ($default == 'w') {
$scale = $scale_w;
} elseif ($default == 'h') {
$scale = $scale_h;
} else {
$scale = min($scale_w, $scale_h);
}
if ($scale == 1 && $scale_h == $scale_w && $this->info['mime'] != 'image/png') {
return;
}
$new_width = (int)($this->info['width'] * $scale);
$new_height = (int)($this->info['height'] * $scale);
$xpos = (int)(($width - $new_width) / 2);
$ypos = (int)(($height - $new_height) / 2);
$image = $this->image; // this is the image object
if ($method == 'SCALE') {
$image->scaleImage($new_width, $new_height);
} elseif ($method == 'THUMB') {
$image->thumbnailImage($new_width, $new_height, false);
} elseif ($method == 'RESIZE') {
$image->resizeImage($new_width, $new_height, $filter, 1);
}
if ($this->info['mime'] == 'image/png') {
$background = 'none';
} else {
$background = 'white';
}
$canvas = $this->create(); // creates an empty Imagick instance
$canvas->newImage($width, $height, new ImagickPixel($background));
$canvas->compositeImage($image, imagick::COMPOSITE_OVER, $xpos, $ypos);
$this->info['width'] = $width;
$this->info['height'] = $height;
$this->image = $canvas;
$image->clear();
$image->destroy();
}
Code: Select all
<?php
class Image {
private $file;
private $image;
private $info;
public function __construct($file) {
if (extension_loaded('imagick')) {
if (file_exists($file)) {
$this->file = $file;
$image = new Imagick();
$image->readImage($file);
$info = $image->identifyImage(true);
$this->info = array(
'width' => $info['geometry']['width'],
'height' => $info['geometry']['height'],
'filesize' => $info['fileSize'],
'compression' => $info['compression'],
'signature' => $info['signature'],
'colorspace' => $info['colorSpace'],
'units' => $info['units'],
'type' => $info['type'],
'mime' => $info['mimetype']
);
if ($this->info['mime'] == 'image/png') {
$image->setFormat('png24');
}
$this->image = $image;
} else {
exit('Error: Could not load image ' . $file . '!');
}
} else {
exit('Error: The Imagick component is not installed on your server!');
}
}
private function create($file = false) {
if ($file) {
return new Imagick($file);
} else {
return new Imagick();
}
}
public function perspective($offset = array(), $background = 'transparent') {
if (count($offset) > 7) {
$points = array(0,0,
(float)$offset['transform_topleft_x'], (float)$offset['transform_topleft_y'],
0, $this->image->getImageHeight(),
(float)$offset['transform_bottomleft_x'], (float)$offset['transform_bottomleft_y'],
$this->image->getImageWidth(), 0,
(float)$offset['transform_topright_x'], (float)$offset['transform_topright_y'],
$this->image->getImageWidth(), $this->image->getImageHeight(),
(float)$offset['transform_bottomright_x'], (float)$offset['transform_bottomright_y']
);
$this->image->setImageMatte(true);
$this->image->setImageMatteColor($background);
$this->image->setImageVirtualPixelMethod(Imagick::VIRTUALPIXELMETHOD_TRANSPARENT);
$this->image->distortImage(Imagick::DISTORTION_PERSPECTIVE, $points, true);
}
}
public function save($file, $quality = 90) {
$info = pathinfo($file);
$extension = strtolower($info['extension']);
if (is_object($this->image)) {
if ($extension == 'jpeg' || $extension == 'jpg') {
$this->image->setImageFormat('jpg');
$this->image->setImageCompression(imagick::COMPRESSION_JPEG2000);
$this->image->setImageCompressionQuality($quality);
$this->image->stripImage();
} elseif ($extension == 'png') {
$this->image->setImageFormat('png');
$this->image->setImageCompression(0);
} elseif ($extension == 'gif') {
$this->image->setImageFormat('gif');
}
$this->image->writeImage($file);
}
}
public function output() {
return $this->image;
}
public function base64output($quality = 90) {
if ($this->info['mime']) {
$response = new Response();
$response->addHeader('Content-Type: ' . $this->info['mime']);
$response->addHeader('Content-transfer-encoding: base64');
$response->addHeader('Expires: Sun, 01 Jan 2014 00:00:00 GMT');
$response->addHeader('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');
$response->addHeader('Cache-Control: post-check=0, pre-check=0');
$response->addHeader('Pragma: no-cache');
if ($this->info['mime'] == 'image/jpeg') {
$this->image->setImageFormat('jpg');
$this->image->setImageCompression(imagick::COMPRESSION_JPEG2000);
$this->image->setImageCompressionQuality($quality);
$this->image->stripImage();
} elseif ($this->info['mime'] == 'image/png') {
$this->image->setImageFormat('png');
$this->image->setImageCompression(0);
} elseif ($this->info['mime'] == 'image/gif') {
$this->image->setImageFormat('gif');
}
ob_start();
echo $this->image;
return base64_encode(ob_get_clean());
}
}
public function resize($width = 0, $height = 0, $default = '', $method = 'THUMB', $filter = Imagick::FILTER_CATROM) {
if (!$this->info['width'] || !$this->info['height']) {
return;
}
$xpos = 0;
$ypos = 0;
$scale = 1;
$scale_w = $width / $this->info['width'];
$scale_h = $height / $this->info['height'];
if ($default == 'w') {
$scale = $scale_w;
} elseif ($default == 'h') {
$scale = $scale_h;
} else {
$scale = min($scale_w, $scale_h);
}
if ($scale == 1 && $scale_h == $scale_w && $this->info['mime'] != 'image/png') {
return;
}
$new_width = (int)($this->info['width'] * $scale);
$new_height = (int)($this->info['height'] * $scale);
$xpos = (int)(($width - $new_width) / 2);
$ypos = (int)(($height - $new_height) / 2);
$image = $this->image;
if ($method == 'SCALE') {
$image->scaleImage($new_width, $new_height);
} elseif ($method == 'THUMB') {
$image->thumbnailImage($new_width, $new_height, false);
} elseif ($method == 'RESIZE') {
$image->resizeImage($new_width, $new_height, $filter, 1);
}
if ($this->info['mime'] == 'image/png') {
$background = 'none';
} else {
$background = 'white';
}
$canvas = $this->create();
$canvas->newImage($width, $height, new ImagickPixel($background));
$canvas->compositeImage($image, imagick::COMPOSITE_OVER, $xpos, $ypos);
$this->info['width'] = $width;
$this->info['height'] = $height;
$this->image = $canvas;
$image->clear();
$image->destroy();
}
public function scale($width = 0, $height = 0, $method = 'THUMB', $filter = Imagick::FILTER_CATROM) {
if ($method == 'SCALE') {
$this->image->scaleImage($width, $height);
} elseif ($method == 'THUMB') {
$this->image->thumbnailImage($width, $height, false);
} elseif ($method == 'RESIZE') {
$this->image->resizeImage($width, $height, $filter, 1);
}
$this->info['width'] = $this->image->getImageWidth();
$this->info['height'] = $this->image->getImageHeight();
}
public function watermark($file, $position = 'bottomright', $x = 0, $y = 0) {
$watermark = $this->create($file);
$watermark_width = $watermark->getImageWidth();
$watermark_height = $watermark->getImageHeight();
switch($position) {
case 'topleft':
$watermark_pos_x = 0;
$watermark_pos_y = 0;
break;
case 'topright':
$watermark_pos_x = $this->info['width'] - $watermark_width;
$watermark_pos_y = 0;
break;
case 'bottomleft':
$watermark_pos_x = 0;
$watermark_pos_y = $this->info['height'] - $watermark_height;
break;
case 'bottomright':
$watermark_pos_x = $this->info['width'] - $watermark_width;
$watermark_pos_y = $this->info['height'] - $watermark_height;
break;
case 'custom':
$watermark_pos_x = $x;
$watermark_pos_y = $y;
break;
}
$image = $this->image;
$image->compositeImage($watermark, imagick::COMPOSITE_OVER, $watermark_pos_x, $watermark_pos_y);
$this->image = $image;
}
public function opacity($opacity) {
if ($opacity < 1) {
$this->image->evaluateImage(Imagick::EVALUATE_MULTIPLY, $opacity, Imagick::CHANNEL_ALPHA);
}
}
public function crop($top_x, $top_y, $bottom_x, $bottom_y) {
$this->image->cropImage($bottom_x, $bottom_y, $top_x, $top_y);
$this->info['width'] = $this->image->getImageWidth();
$this->info['height'] = $this->image->getImageHeight();
}
public function rotate($degree, $color = '#00000000') {
$this->image->rotateImage(new ImagickPixel($color), $degree);
$this->info['width'] = $this->image->getImageWidth();
$this->info['height'] = $this->image->getImageHeight();
}
public function composite($watermark, $x = 0, $y = 0) {
$this->image->compositeImage($watermark, imagick::COMPOSITE_OVER, $x, $y);
$this->info['width'] = $this->image->getImageWidth();
$this->info['height'] = $this->image->getImageHeight();
}
private function merge($file, $x = 0, $y = 0, $opacity = 1) {
$merge = $this->create($file);
if ($opacity < 1) {
$merge->evaluateImage(Imagick::EVALUATE_MULTIPLY, $opacity, Imagick::CHANNEL_ALPHA);
}
$this->image->compositeImage($merge, imagick::COMPOSITE_OVER, $x, $y);
}
public function __destruct() {
$this->image->clear();
$this->image->destroy();
}
}