Crayons
Crayons

Reputation: 2066

ImageMagick White to Transparent Background While Maintaining White Object

I am using PHP's ImageMagick to turn the white background of an image, transparent. I pass the image URL to this PHP script and it returns the image.

<?php

# grab the remote image url
$imgUrl = $_GET['img'];

# create new ImageMagick object
$im = new Imagick($imgUrl);

# remove extra white space
$im->clipImage(0);

# convert white background to transparent
$im->paintTransparentImage($im->getImageBackgroundColor(), 0, 3000);

# resize image --- passing 0 as width invokes proportional scaling
$im->resizeImage(0, 200, Imagick::FILTER_LANCZOS, 1);

# set resulting image format as png
$im->setImageFormat('png');

# set header type as PNG image
header('Content-Type: image/png');

# output the new image
echo $im->getImageBlob();

These transformations work pretty well. However, if I have an image with a white object, it doesn't work very well as a result of passing a fuzz value to paintTransparentImage(); which is how I am cleaning up jagged edges.

Here's an example of the result, note the white sofa:

enter image description here

If I don't pass a fuzz value, then I get a proper cut, but i'm left with messy edges:

enter image description here

I have attempted to use resizeImage() in an effort to achieve what's called 'spatial anti-aliasing' (blow up the image really big -> use paintTransparentImage() -> shrink image back down), but I didn't notice any significant changes.

Is there something I can do to better handle these really white images? I've played about with trimImage() and edgeImage(), but I'm not able to get the results i'm after.

Worst case scenario, (though not ideal), is there a means of identifying if an image contains some percentage of a particular colour? IE. if image contains >90% white pixels then I could run paintTransparentImage() with a fuzz value of 0 instead of 3000 which would at least give me a proper cut.

Thanks.

Upvotes: 4

Views: 9395

Answers (3)

Raphu
Raphu

Reputation: 1

update in 2021 => imagick module version 3.4.4 (you're welcome :o) ):

$imgick = new Imagick($pathToFile);
$aTaille=$imgick->getImageGeometry();
$colorToTransparent=$imgick->getImagePixelColor(0,0); 
$imgick->borderImage($colorToTransparent, 10, 10);

$imgick->floodFillPaintImage("rgb(255, 0, 255)", 2500, $colorToTransparent, 0 , 0, false);

$imgick->transparentPaintImage("rgb(255,0,255)", 0, 100, false);

$imgick->cropImage($aTaille['width'], $aTaille['height'], 10, 10);

$imgick->setImageFormat('png'); 

# set header type as PNG image
header('Content-Type: image/png');
# output the new image
echo $im->getImageBlob();

Upvotes: 0

VishalParkash
VishalParkash

Reputation: 486

You can try the exec command. It worked for me. You can refer to this link,

<?php
    $rand_new = rand();
    $target_dir = 'yourFolder/';
    $imageName = 'yourImage';
    $image = $target_dir.$imageName;
    $imageFileType = strtolower(pathinfo($image,PATHINFO_EXTENSION));
    $new_image = time().".png";
    exec("convert $image -fill none -fuzz 10% -draw 'matte 0,0 floodfill' -flop  -draw 'matte 0,0 floodfill' -flop $new_image");
?>

Upvotes: -1

Crayons
Crayons

Reputation: 2066

SOLUTION:

Replace white background with some other colour first, then change that colour to transparent.

<?php

# get img url
$imgUrl = $_GET['img'];

# create new ImageMagick object from image url
$im = new Imagick($imgUrl);

# replace white background with fuchsia
$im->floodFillPaintImage("rgb(255, 0, 255)", 2500, "rgb(255,255,255)", 0 , 0, false);

#make fuchsia transparent
$im->paintTransparentImage("rgb(255,0,255)", 0, 10);

# resize image --- passing 0 as width invokes proportional scaling
$im->resizeImage(0, 200, Imagick::FILTER_LANCZOS, 1);

# set resulting image format as png
$im->setImageFormat('png');

# set header type as PNG image
header('Content-Type: image/png');

# output the new image
echo $im->getImageBlob();

enter image description here

enter image description here

enter image description here

enter image description here

Upvotes: 12

Related Questions