Imagick :: paintOpaqueImage忽略半透明像素

时间:2015-09-11 04:48:53

标签: php image-processing imagick

我注意到Imagick::paintOpaqueImage仅对alpha值为1的像素进行操作。这会使转换后的图像留下大量剩余的I' m试图替换的像素。以此测试图像为例

enter image description here

此代码用蓝色像素替换蓝色像素。

$img->paintOpaqueImage('rgb(12,0,245)', 'rgb(255,0,0)', 0);

结果只是替换了纯蓝色像素。

enter image description here

注意该测试图像中的所有像素(除了完全透明的像素)都是相同的蓝色。唯一的区别是alpha值。另请注意,我为$fuzz参数使用了值0。在我发现真正的问题之前,我最初碰到了这一点,这导致了它自己的不良结果。

我使用ImagickPixelIterator将解决方案整合在一起;它clones当前像素,并将当前像素和克隆像素的alpha值设置为1,以强制ImagickPixel::isSimilar在alpha值方面非常有效地工作。

$img      = new Imagick('./test-paint-opaque-image.png');
$iterator = new ImagickPixelIterator($img);
$target   = new ImagickPixel('rgb(12,0,245)'); // blue
$fill     = new ImagickPixel('rgb(255,0,0)');  // red
$fuzz     = 0;

foreach($iterator as $pixels) {
    foreach($pixels as $curPixel) {
        // Modify the alpha of the comparePixel so it won't throw off the isSimilar() check
        $comparePixel = clone $curPixel;
        $fOrigAlpha   = $curPixel->getColorValue(Imagick::COLOR_ALPHA);

        // Bail on fully transparent pixels
        if($fOrigAlpha == 0)
            continue;

        // It seems the only way isSimilar will work is when the alpha is 1 for both pixels...
        $comparePixel->setColorValue(Imagick::COLOR_ALPHA, 1);
        $curPixel->setColorValue(Imagick::COLOR_ALPHA, 1);

        if($comparePixel->isSimilar($target, $fuzz)) {
            $curPixel->setColorValue(Imagick::COLOR_RED,   $fill->getColorValue(Imagick::COLOR_RED));
            $curPixel->setColorValue(Imagick::COLOR_GREEN, $fill->getColorValue(Imagick::COLOR_GREEN));
            $curPixel->setColorValue(Imagick::COLOR_BLUE,  $fill->getColorValue(Imagick::COLOR_BLUE));

            // Set the modified alpha back to what it was after the color change
            if($fOrigAlpha > 0) {
                echo "Setting alpha to $fOrigAlpha\n";
                $curPixel->setColorValue(Imagick::COLOR_ALPHA, $fOrigAlpha);
            }
        }
    }
    $iterator->syncIterator();
}

结果是一个闪亮的红色图像,保留了半透明(和完全透明)的像素。

enter image description here

主要问题,最后让我想到的问题是这种方法很慢。有没有办法直接使用PHP Imagick::paintOpaqueImage进行这种颜色转换?

0 个答案:

没有答案