PHP GD的图像重新着色功能太慢
我用PHP编写了这个函数,用于将图片从一种颜色更改为另一种颜色,我非常喜欢它。对我来说,它看起来非常符合我的目的,而且它似乎很好地考虑了原始图像的亮度。但是,它很慢。根据我正在处理的图像大小,重新收集一张图像大约需要23秒。我知道减速是通过每个像素循环实现的,所以我通过Imagick类尝试了Imagemagick函数的一些不同组合,但是我找不到任何组合,我喜欢的结果和我的函数一样多。有没有一种方法,也许使用C,我可以将它作为Imagemagick的某种插件来编写,甚至可以通过Imagick类来使用它,这样我就不必通过exec()之类的东西来运行它?我还试着使用Imagick的像素迭代器,并查看了fxImage,但这些都一样慢,如果不是更糟的话PHP GD的图像重新着色功能太慢,php,image-processing,imagemagick,gd,imagick,Php,Image Processing,Imagemagick,Gd,Imagick,我用PHP编写了这个函数,用于将图片从一种颜色更改为另一种颜色,我非常喜欢它。对我来说,它看起来非常符合我的目的,而且它似乎很好地考虑了原始图像的亮度。但是,它很慢。根据我正在处理的图像大小,重新收集一张图像大约需要23秒。我知道减速是通过每个像素循环实现的,所以我通过Imagick类尝试了Imagemagick函数的一些不同组合,但是我找不到任何组合,我喜欢的结果和我的函数一样多。有没有一种方法,也许使用C,我可以将它作为Imagemagick的某种插件来编写,甚至可以通过Imagick类来使
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);
}
}
公共函数着色($img,$rgb){
imagealphablending($img,true);
imagesavealpha($img,true);
//获取图像的宽度和高度
$iwidth=imagesx($img);
$iheight=imagesy($img);
//循环通过每个像素
对于($y=0;$y 24)&0xFF;
$or=($orgb>>16)和0xFF;
$og=($orgb>>8)和0xFF;
$ob=$orgb&0xFF;
//将原始rgb值和新rgb值相加
$total_original=$or+$og+$ob;
$total_new=$rgb[0]+$rgb[1]+$rgb[2];
//使用rgb通道的平均值调整亮度
$bright=-127+$total_new/3;
//取新颜色亮度和旧颜色亮度的平均差值,加上亮度调整,然后取整
$adjustment=圆形($bright+($total\u new-$total\u original)/-3);
//将每个通道设置为新颜色通道,添加调整,并确保结果不小于0或大于255
$r=最大值(0,最小值($adjustment+$rgb[0],255));
$g=最大值(0,最小值($adjustment+$rgb[1],255));
$b=最大值(0,最小值($adjustment+$rgb[2],255));
//替换原始像素
$nrgb=imagecolorallocatealpha($img、$r、$g、$b、$oa);
imagesetpixel($img,$x,$y,$nrgb);
}
}
您可以向ImageMagick添加所谓的模块
,尽管这涉及到很多问题
首先,您需要ImageMagick的源代码和开发环境,例如编译器和make
等
然后,您需要使用配置标志——modules=yes
构建ImageMagick
一旦构建了模块,就需要在命令行上实际调用它,或者修改PHP/Perl绑定来实现这一点。本质上,它在命令行中看起来是这样的:
convert image.png -process YourModuleName <YourModuleParameters> output.png
convert image.png-处理YourModuleName output.png
还有更多的信息——虽然它是为Windows编写的,但您可以在Linux上使用它——我也在Mac OSX上成功地构建了模块。您可以将所谓的
模块添加到ImageMagick中,尽管这相当复杂
首先,您需要ImageMagick的源代码和开发环境,例如编译器和make
等
然后,您需要使用配置标志——modules=yes
构建ImageMagick
一旦构建了模块,就需要在命令行上实际调用它,或者修改PHP/Perl绑定来实现这一点。本质上,它在命令行中看起来是这样的:
convert image.png -process YourModuleName <YourModuleParameters> output.png
convert image.png-处理YourModuleName output.png
还有更多的信息——虽然它是为Windows编写的,但您可以在Linux上使用它——我也在Mac OSX上成功地构建了模块。这不仅仅是一个答案,更是一个建议,但我渴望一种评论格式
(1) 颜色矩阵
据我所知,您所做的颜色增强本质上是根据用户提供的颜色对现有颜色进行调整。这让我想起了利用-color matrix
操作符(或在PHP中)的脚本
这可以定义为
new_red = (delta) * red + 0 * green + 0 * blue
new_green = 0 * red + (delta) * green + 0 * blue
new_blue = 0 * red + 0 * green + (delta) * blue
目标是计算用户提供颜色的
增量,并直接调整矩阵
示例从白色计算给定颜色。
(2) 远离RGB色彩空间
我想到的另一件事是,在你的例子中,计算可能只是调整颜色的强度。忽略给定的颜色一分钟,我们可以考虑如何在颜色空间中增强图像。如果我们将图像转换为不同的颜色空间,我们可以通过简单地调整亮度通道来应用相同的颜色增强
$wand=newimagick('rose:');
//改变色彩空间
$wand->setImageColorspace(Imagick::COLORSPACE\u YCBCR);
//让quantum一起工作
$qr=$wand->getQuantumRange()['quantumRangeLong'];
//执行增强计算(例如硬编码)
$blackPoint=0.1*$qr;
$whitePoint=0.9*$qr;
$gamma=1;
$sigmod=0.001;
$Y=Imagick::CHANNEL_RED;//红色是该颜色空间中的第一个通道,或Y。
//Re水平Y
$wand->levelImage($blackPoint、$gamma、$whitePoint、$Y);
//调整Y的对比度
$wand->SIGMODAL对比图像($sigmod,1,1,$Y);
//把它放回RGB
$wand->setImageColorspace(Imagick::COLORSPACE\u SRGB);
希望这会有所帮助。这不仅仅是一个答案,更是一个建议,但我渴望得到一个评论格式 (1) 颜色矩阵 据我所知,您所做的颜色增强本质上是根据用户提供的颜色对现有颜色进行调整。这让我想起了利用
-color matrix
操作符(或在PHP中)的脚本
这可以定义为
new_red = (delta) * red + 0 * green + 0 * blue
new_green = 0 * red + (delta) * green + 0 * blue
new_blue = 0 * red + 0 * green + (delta) * blue
目标是计算用户提供颜色的增量,并直接调整矩阵
示例从白色计算给定颜色。
(2) 远离RGB色彩空间
我想到的另一件事是,在你的例子中,计算结果可以是m