Magento - Removing the black background from automatic thumbnails? - php

On a Magento site, I’m just uploading one picture per product, and using that as the base, small and thumbnail images. However, my pictures aren’t square, so I’m getting a black background added to the thumbnail that’s created. Any ideas how to change that to a white background?
http://www.magentocommerce.com/?ACT=25&fid=10&aid=10785_osKeOnfKFLFvgqVYbr0j&board_id=1
I’ve searched for this but can’t find a decent answer anywhere…

I found a workaround for this. The side effect is that the class used for image resize will fill all images with white (even transparent ones), but this doesn't realy affect Magento since it doesn't use transparent fill anyway. So to solve the issue do this:
Go to lib\Varien\Image\Adapter\Gd2.php in your magento folder
Find this line
$this->_fillBackgroundColor($newImage);
and replace it with this line
$this->_fillBackgroundColor($newImage,$frameWidth,$frameWidth);
Find this line
private function _fillBackgroundColor(&$imageResourceTo)
and replace it with this
private function _fillBackgroundColor(&$imageResourceTo,$w,$h)
Find this code
if (!imagefill($imageResourceTo, 0, 0, $color)) {
throw new Exception("Failed to fill image background with color {$r} {$g} {$b}.");
}
and replace it with this
imagefilledrectangle($imageResourceTo,0,0,$w,$h,$color);
That is it. The problem comes from the PHP function imagefill in Gd2 not working on some setings. This is a workaround using imagefilledrectangle, and worked for me. Hope it solves your problem too.

Correction on point 4 from Adi's answer:
4. Find this code
if (!imagefill($imageResourceTo, 0, 0, $color)) { throw new Exception("Failed to fill image background with color {$r} {$g} {$b}."); }
and replace it with:
if (!imagefilledrectangle($imageResourceTo,0,0,$w,$h,$color)) {
throw new Exception("Failed to fill image background with color {$r} {$g} {$b}.");

Varien_Image which is used in Magento offers a possibility to set background color of scaled image. You can use similar code somewhere before outputting the image (resize method?) to make background white:
$image->backgroundColor(array(255, 255, 255));

Adi's answer led me in the right direction, but I was still getting a black line on my images. I discovered that when an image is cropped, Magento creates a canvas background, then the image on top of it. The canvas was producing the black line on my images.
I managed to fix it by adding Adi's changes, and then additionally, in the crop() function (in the same file), I added:
list($r, $g, $b) = $this->_backgroundColor;
$bg_color = imagecolorallocate($canvas, $r, $g, $b);
imagefill($canvas, 0, 0, $bg_color);
After the function (around line 554, after adi's changes):
imagecopyresampled
Now my images have the background colour they should have!
Another thing to note, instead of editing this file directly in the core, it should be copied to:
app/code/local/Varien/Image/Adapter/Gd2.php
Hope this helps someone struggling with the same issue.

Related

cropping an image via a php file

so i have an image that is originally 1696x1696. i want to use a php file to MIME a png file. what i want the php to do is crop the original file and produce a quarter of the image. Later i plan to use $_GET variables to return which quadrant i want, but for testing/debugging, im just aiming to get the top left quadrant.
here's the code:
Header("Content-type:image/png");
$newImg =imagecreatefrompng('test.png');
//manually entered half height and width
$img=imagecreatetruecolor(848,848);
//here is where the bugs keep flawing the image
imagecopyresampled($img,$newImg,0,0,0,0,1696,1696,1696,1696);
imagepng($img);
imagedestroy($img);
this will produce the image (top, left) like it's supposed to, however it adds several smaller resampled images on top of it. no matter how i toy with it, i cant get it right. i've also tried imagecopy() and cant get it right as well. looked up tutorials and i cant seem to find on that helps.
Your code looks fine. The only thing I would change is to use imagecopyresized() instead of imagecopyresampled() in this use case.
Header("Content-type:image/png");
$source = imagecreatefrompng('images/test.png');
// manually entered half height and width
$thumb = imagecreatetruecolor(848,848);
imagecopyresized($thumb, $source, 0, 0, 0, 0, 1696, 1696, 1696, 1696);
imagepng($thumb);
imagedestroy($thumb);
I am guessing that earlier in your tests, you were overwriting your original image. That would explain the...
however it adds several smaller resampled images on top of it...
...part of your experience. Each time you ran the code, you picked up the previously modified file.
ok, so after enough headbanging and hair-tearing out, i decided to just go back to photoshop and overwrite the .png with my original .psd. starting to get somewhere now. i got my quadrant without all the ridiculousness. when i get a better understanding, i might come back and explain where i kept going wrong

Taking care of transparency using IMagick via PHP makes some images darker

I have a script that handles/scales uploaded images. I noticed that some of the images come out significantly darkened, and through a process of elimination tracked the darkening back to this section of code:
$scaled = new IMagick();
$scaled->newPseudoImage($original->getImageWidth(), $original->getImageHeight(), 'xc:white');
$scaled->compositeImage($original, Imagick::COMPOSITE_DEFAULT, 0, 0);
$scaled->flattenImages();
What I'm doing here is trying to eliminate issues with transparent backgrounds in some images coming through as black when I convert to jpg.
Does anyone have any idea which part of this code is darkening the image and what a good way to fix it might be?
Edit: Still haven't figured out the heart of this issue, but I did find that I can avoid doing this to images that don't need it by wrapping it in:
if($original->getImageAlphaChannel()){

Overlay PNG on JPG using Imagick

I have the last few hours tried to get a PNG logo with a transparent background on top of a JPG background. I have tried several ways and with several globals as well, but I do not seem to be able to get the result I want.
"First Attempt":
$overlay = new Imagick('overlay.png');
$image = new Imagick('background.jpg');
$image->compositeImage($overlay, Imagick::COMPOSITE_DEFAULT, 10, 10);
$image->writeImage('background.jpg'); //replace original background
$overlay->destroy();
$image->destroy();
As you can see, the Jaguar logo is all black.
"Second Attempt"
$overlay = new Imagick('overlay.png');
$image = new Imagick('background.jpg');
$image->setImageColorspace($overlay->getImageColorspace() );
$image->compositeImage($overlay, Imagick::COMPOSITE_DEFAULT, 10, 10);
$image->writeImage('background.jpg'); //replace original background
$overlay->destroy();
$image->destroy();
This one the Jaguar logo looks like it should, but the background is all messed up now.
I have tried with Imagick::setImageMatte and tried to add the overlay to a white background (thought I does need to have a transparent background) and still it won't display the image properly. I have tried many other variations of the 2 above snippets but they all seem to make the PNG completely or partial black.
What am I missing or doing wrong? Can anyone give me a nudge in the right direction?
Please note this needs to be done in PHP.
Thank you very much!
I am a huge idiot! Turns out I forgot to convert the images from CMYK to RGB.
For anyone who might encounter this in the future, learn from my incompetence!
I was trying to overlay a png with transparency over the top of another png. I used this line from the PHP docs.
$src1->compositeImage($src2, Imagick::COMPOSITE_MATHEMATICS, 0, 0);
but I was getting the same problem. The overlay came through as black only. Changing it to this seemed to fix the colours.
$src1->compositeImage($src2, Imagick::COMPOSITE_DEFAULT, 0, 0);

php image manipulation - fade to transparency

does anyone know how to apply fade effect to an image using PHP ? what I am looking for is a way to apply gradient transparency ( i mean : at the top , the image is opaque , which gradually gets more and more transparent , and at the bottom it is completely transparent).
i have been reading up on http://php.net/manual/en/function.imagecolortransparent.php , but did not see anything about applying a gradient effect to an image.
i also read : PHP - Generate transparency (or opacity) gradient using image , but it kinda trailed off without any solution!
I am also open to any other suggestion / libraries that can do this from command line.
Obviously you'll need to work with a png for this effect, but you can convert any png into a jpg using php. The following question I believe covers what you are asking about. Part of the code will have to be removed to clear the image reflection effect.
Can You Get a Transparent Gradient using PHP ImageMagick?
The piece of code which seems to do what you are trying to accomplish is:
$im = new Imagick('image.jpg'); //Reference image location
if (!$im->getImageAlphaChannel()) {
$im->setImageAlphaChannel(Imagick::ALPHACHANNEL_SET);
}
$refl = $im->clone();
$refl->flipImage();
$gradient = new Imagick();
$gradient->newPseudoImage($refl->getImageWidth() + 10, $refl->getImageHeight() + 10, "gradient:transparent-black");

Imagick roundCorners makes image half-transparant

I'm in the process of writing an image script for a website I'm making, and for one of the image modes I need to both crop the image and make round corners for it. This is the code I'm using now:
$img = new Imagick();
$img->readImageBlob($data);
$img->resizeImage($width, $height, $img->FILTER_GAUSSIAN, 1);
$canvas = new Imagick();
$canvas->newImage($size[0], $size[1], new ImagickPixel('white'));
$canvas->compositeImage($img, imagick::COMPOSITE_OVER, 0, 0);
$canvas->roundCorners(10, 10);
$canvas->setImageFormat('png');
Resulting image
However, the resulting image is about half-transparent, as seen above, except for a 10-ish px border around the edge, created by roundCorner I assume. I've tried a lot of different ways of doing this, including cropping $img directly and roundCorner on it, but then the result is without round corners.
I suspect compositeImage to be the thief in this drama, but I can't say for sure. Anyone?
EDIT: Correction: If I do the crop and round solution, I end up with rounded corners, but they have a black background. This is the code I'm using here. Anyone spot the error/solution?
$img = new Imagick();
$img->readImageBlob($data);
$img->resizeImage($width, $height, $img->FILTER_GAUSSIAN, 1);
$img->cropImage($size[0], $size[1], 0, 0);
$img->roundCorners(10, 10);
EDIT 2:
The solution to the crop and round resolution was to make sure it's a png, so that is has alpha-support. However, the result is the same as the one produced from my original code.
EDIT 3:
Tried this script on my deployment server, and it worked as I wanted it to, so it seems like there's some problem with the version of imagick / php-imagick shipped with macports. Thanks for all the help!
You can tell imagemagick to give you an alpha background with
$img->setImageAlphaChannel ( imagick::ALPHACHANNEL_TRANSPARENT )
or try setting the image format to PNG24 explicitly before doing any transformations.
Order is important here, the image needs an alpha channel before you expose the background.
It was a problem with the version of Imagick / php-imagick shipped with current macports. Haven't solved it for my computer, but the script is working as intended on my deployment server.

Categories