ImageMagick将白色转换为透明背景同时保持白色对象

4
我正在使用PHP的ImageMagick将图像的白色背景变成透明的。 我将图片URL传递给这个PHP脚本,并返回图像。
<?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();

这些转换效果相当不错。但是,如果我的图片中有一个白色物体,通过将模糊值传递给paintTransparentImage()来清除锯齿边缘的结果就不是很好了。
下面是结果示例,请注意白色沙发:

enter image description here

如果我不传递模糊值,那么我会得到一个适当的裁剪,但是边缘会很凌乱。

enter image description here

我尝试使用 resizeImage() 来实现所谓的“空间抗锯齿”(将图像放大 -> 使用 paintTransparentImage() -> 缩小图像),但我没有注意到任何显着的变化。

有什么办法可以更好地处理这些非常白的图像吗?我已经尝试了 trimImage()edgeImage(),但我无法获得我想要的结果。

最坏的情况是,(虽然不理想),是否有一种方法可以识别图像是否包含特定颜色的某个百分比?例如,如果图像包含 >90% 的白色像素,则我可以以模糊值为0而不是3000运行 paintTransparentImage(),这至少会给我一个正确的切割。

谢谢。


已解决。编辑帖子以显示解决方案。 - Crayons
3个回答

11

解决方案:

首先将白色背景替换为其他颜色,然后将该颜色更改为透明色。

<?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();

这里输入图片描述

这里输入图片描述

这里输入图片描述

这里输入图片描述


0

2021年更新 => imagick模块版本3.4.4(不客气 :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();

-1

你可以尝试使用exec命令。这对我很有效。 你可以参考this链接,

<?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");
?>

1
Exec()是一个PHP函数,用于执行一些外部程序。在这种情况下,您只是使用ImageMagic的命令行版本。这与问题无关。 - Crayons
他有提到不要使用CLI来解决问题吗?我想这会帮助他得到他想要的东西。 - VishalParkash
作为这个问题的作者,我可以说我在2017年4月已经解决了这个问题,而你使用“exec()”的回答与我的问题毫无关系,我的朋友。 - Crayons
好的,虽然可能对其他人有帮助。 - VishalParkash

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接