【问题标题】:Image Recoloring Function For PHP GD Too SlowPHP GD 的图像重新着色功能太慢
【发布时间】:2015-12-28 23:19:54
【问题描述】:

我用 PHP 编写了这个函数,用于将图片从一种颜色变为另一种颜色,我非常喜欢它。对我来说,它看起来非常逼真,并且似乎很好地考虑了原始图像的亮度。但是,它很慢。使用我正在使用的图像尺寸,重新着色一张图像大约需要 23 秒。我知道减速带来自循环遍历每个像素,所以我通过 Imagick 类尝试了 Imagemagick 函数的一些不同组合,但我找不到任何我喜欢我的函数结果的组合。有没有办法,也许使用 C,我可以把它写成 Imagemagick 的某种插件,甚至通过 Imagick 类使它可用,这样我就不必通过像 exec() 这样的东西来运行它?我也尝试过使用 Imagick 的 PixelIterator,并查看了 fxImage,但这些都一样慢,如果不是更糟的话。

public function colorize($img, $rgb) {
    imagealphablending($img, true);
    imagesavealpha($img, true);

    // get width and height of image
    $iwidth = imagesx($img);
    $iheight = imagesy($img);

    // loop through each pixel
    for ($y=0; $y<$iheight; $y++) for ($x=0; $x<$iwidth; $x++) {
        // get all original r, g, b, a values of the pixel
        $orgb = imagecolorat($img, $x, $y);
        $oa = ($orgb >> 24) & 0xFF;
        $or = ($orgb >> 16) & 0xFF;
        $og = ($orgb >> 8) & 0xFF;
        $ob = $orgb & 0xFF;

        // add up orginal rgb values and new rgb values
        $total_original = $or + $og + $ob;
        $total_new = $rgb[0] + $rgb[1] + $rgb[2];

        // adjust brightness using average of rgb channels
        $bright = -127 + $total_new/3;
        // take average difference between new color's brightness and old color's brightness, add brightness adjustment to it, and round
        $adjustment = round($bright + ($total_new - $total_original) / -3);

        // set each channel to new color channels, add the adjustment, and make sure the result isn't less than 0 or greater than 255
        $r = max(0,min($adjustment + $rgb[0],255));
        $g = max(0,min($adjustment + $rgb[1],255));
        $b = max(0,min($adjustment + $rgb[2],255));

        // replace original pixel
        $nrgb = imagecolorallocatealpha($img, $r, $g, $b, $oa);
        imagesetpixel($img, $x, $y, $nrgb);
    }
}

【问题讨论】:

  • 您能否提供一个示例图像/RGB 值用于您的基准测试?

标签: php image-processing imagemagick gd imagick


【解决方案1】:

您可以将所谓的modules 添加到 ImageMagick - 尽管它非常复杂。

首先,您需要 ImageMagick 的源代码和开发环境 - 例如。编译器和make等。

然后您需要使用配置标志 --with-modules=yes 构建 ImageMagick。

构建模块后,您需要在命令行上实际调用它,或者修改您的 PHP/Perl 绑定来执行此操作。本质上,它在命令行中看起来像这样:

convert image.png -process YourModuleName <YourModuleParameters> output.png

有更多信息here - 虽然它是为 Windows 编写的,但你可以在 Linux 上关注它 - 我也在 Mac OSX 上成功构建了模块。

【讨论】:

    【解决方案2】:

    这是比答案更多的建议,但是对于评论格式来说很长。

    (1) 颜色矩阵

    据我所知,您所做的颜色增强本质上是根据用户提供的颜色对现有颜色进行调整。这让我想起了 Fred's whiteblance 脚本,它利用了 -color-matrix 运算符(或 PHP 中的 Imagick::colorMatrixImage())。

    这可以定义为...

     new_red   = (delta) * red +       0 * green +       0 * blue
     new_green =       0 * red + (delta) * green +       0 * blue
     new_blue  =       0 * red +       0 * green + (delta) * blue
    

    目标是计算用户提供的颜色的delta,并直接调整矩阵。

    示例从白色计算给定颜色。

    $delta_red   = 0xFF/$rgb[0];
    $delta_green = 0xFF/$rgb[1];
    $delta_blue  = 0xFF/$rgb[2];
    $wand = new Imagick($img);
    $wand->colorMatrixImage([$delta_red,            0,           0,
                                      0, $delta_green,           0,
                                      0,            0, $delta_blue]);
    

    (2) 远离 RGB 色彩空间

    我想到的另一件事是您示例中的计算可能只是调整颜色的强度。暂时忽略给定的颜色,我们可以考虑如何在YCbCR色彩空间中增强图像。如果我们将图像转换为不同的色彩空间,我们可以通过简单地调整亮度通道来应用相同的色彩增强。

    $wand = new Imagick('rose:');
    // Change colorspace
    $wand->setImageColorspace(Imagick::COLORSPACE_YCBCR);
    
    // Get quantum to work with
    $qr = $wand->getQuantumRange()['quantumRangeLong'];
    
    // Perform enhancement calculations (hard-coded for example)
    $blackPoint = 0.1 * $qr;
    $whitePoint = 0.9 * $qr;
    $gamma = 1;
    $sigmod = 0.001;
    
    $Y = Imagick::CHANNEL_RED; // Red is the first channel, or Y in this colorspace.
    // Re-level Y 
    $wand->levelImage($blackPoint, $gamma, $whitePoint, $Y);
    // Adjust contrast of Y
    $wand->sigmoidalContrastImage($sigmod, 1, 1, $Y);
    
    // Put it back RGB
    $wand->setImageColorspace(Imagick::COLORSPACE_SRGB);
    

    希望对您有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-10-17
      • 1970-01-01
      • 1970-01-01
      • 2015-07-02
      • 1970-01-01
      • 2015-01-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多