PHP:如何将“接近白色”的颜色表达出来?

5
我有一个裁剪图片白边的函数,大致如下:
if(imagecolorat($img, $x, $top) != 0xFFFFFF) {
    //sets where the top part of the image is trimmed
}

问题在于有些图片偶尔会出现一个接近白色的杂点,虽然不容易被注意到,但由于其像素值并非精确为0xFFFFFF,而是0xFFFEFF或其他数值,导致剪裁出现了问题。如何改写上述语句,以便对那些接近白色图片的像素值评估为真,比如下降到0xFDFDFD,而无需测试每个可能的数值。


手动操作需要按组进行范围比较。 - Ja͢ck
5个回答

6
$color = imagecolorat($img, $x, $top);
$color = array(
    'red'   => ($color >> 16) & 0xFF,
    'green' => ($color >>  8) & 0xFF,
    'blue'  => ($color >>  0) & 0xFF,
);
if ($color['red']   >= 0xFD
 && $color['green'] >= 0xFD
 && $color['blue']  >= 0xFD) {
    //sets where the top part of the image is trimmed
}

有关所使用的运算符的说明,请阅读:


这对我不起作用。它甚至无法将完全白色的图像裁剪。 - L84
@L84:可能是因为你需要使用<而不是>=。不要只是复制粘贴代码,尝试理解它。如果你有理解上的问题,请在评论中提问。这个答案没有包含太多关于做了什么的描述,所以还有一些“工作”需要你去完成。 - hakre
我试图尽快测试它,以便接受答案并不出于无缘无故地保持问题开放。 :) - L84
是的,当它使用<而不是>=时,我已经用FFFFFFE和FFFFFFC进行了检查,它会忽略前者并停在后者。谢谢! - L84

4
要正确检测这些灰白色,您应该将RGB颜色坐标转换为HSV;在HSV中,所有灰白色的S接近于0,V接近于100(归一化)。这个问题有一个带有PHP代码的答案来进行转换,因此使用该代码,您将得到:
$rgb = imagecolorat($img, $x, $top);
$hsv = RBG_TO_HSV(($rgb >> 16) & 0xFF, ($rgb >> 8) & 0xFF, $rgb & 0xFF);
if ($hsv['S'] < .05 && $hsv['V'] > .95) {
    // color is off-white
}

你可以调整常量.05.95来放松或加紧标准,你也可以使用交互式颜色选择器(例如this)来感受在不同SV值下颜色接近白色的程度。请保留HTML标签。

RGB_TO_HSV()需要3个参数,但此处只传递了一个。 - L84
@L84:已编辑以修复,但只是一些位操作。 - Jon

0
这是一种实现的方法。将颜色分解为RGB组件,例如使用$color = 0xFFFEEF,你将得到$red = 0xff; $green = 0xfe; $blue = 0xef'。然后将每个组件与阈值进行比较。如果三个组件都在阈值范围内,则它是“几乎白色”。因此,您的函数应该是类似于以下伪代码:
function is_nearly_white($r, $g, $b) {
    $threshold = 0xfd;
    return ($r > $threshold && $g > $threshold && $b > $threshold);
}

0

通过将"and"应用于RGB整数,您可以检测到几乎白色。基本上这与Alin Roman所说的相同,但更简单一些,只需要一行代码。

if ((imagecolorat($img, $x, $top) & 0xF0F0F0) != 0xF0F0F0) {
    //sets where the top part of the image is trimmed
}

它应该能够检测从0xFFFFFF到0xF0F0F0的颜色。


0

我认为这应该可以完成工作:

$range = 0xFFFFFF - 0xFFFEFF;

if((0xFFFEFF - imagecolorat($img, $x, $top)) < $range){
    // do
}

很遗憾,它并不起作用,它只是将图像过度裁剪到中间。 - L84

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