下面的php代码块应该以this image作为输入snd生成this image作为输出(将黑色转换为黄色,将浅蓝色转换为黑色):
但是,我将this image作为输出。
任何人都可以看到我的代码出现问题吗?
$im = imagecreatefrompng("./input.png");
$width = imagesx($im);
$height = imagesy($im);
$new = imagecreate($width, $height);
imagecopy($new, $im, 0, 0, 0, 0, $width, $height);
imagecolorset($new, imagecolorexact($new, 0, 0, 0), 255, 255, 0);
for($i = 0; $i < $width; $i++) {
for($j = 0; $j < $height; $j++) {
$index = imagecolorat($new, $i, $j);
$rgb = imagecolorsforindex($new, $index);
if($rgb['red'] != 255 && $rgb['green'] != 255 && $rgb['blue'] != 0) {
echo '(' . $i . ', ' . $j . ')' . 'color => (' . (255 - $rgb['blue']) . ', ' . (255 - $rgb['blue']) . ', 0)<br />';
$color = imagecolorallocate($new, 255 - $rgb['blue'], 255 - $rgb['blue'], 0);
imagesetpixel($new, $i, $j, $color);
}
unset($index);
unset($rgb);
}
}
imagepng($new, 'tesst.png');
imagedestroy($im);
imagedestroy($new);
答案 0 :(得分:1)
我认为这里问题的根源在于,当使用基于调色板的图像(例如通过调用imagecreate()
创建的图像)时,可以在调色板中的多个索引处声明相同的颜色。
这意味着,因为您在每次迭代时调用imagecolorallocate()
,调色板最终会变满,imagecolorallocate()
开始返回false
(如果您var_dump($color);
可以看到在imagesetpixel()
电话之前。当转换为整数时,false
的计算结果为零 - 所以当调色板填满时,所有剩余的像素都会有效地转换为背景颜色。
关于这一点你可以做两件事,第一件也许最简单的就是使用真彩色图像,这只是将imagecreate($width, $height);
改为imagecreatetruecolor($width, $height);
的一个简单例子。 / p>
如果你想坚持使用基于调色板的图像(例如出于输出图像数据大小的原因 - 图像包含很少的颜色,基于调色板的图像会相当小),你需要缓存手动分配颜色,以便您可以重复使用它们,如下所示:
// ...
$colors = array();
for ($x = 0; $x < $width; $x++) { // iterate x axis
for ($y = 0; $y < $height; $y++) { // iterate y axis
// Get the color at this index
$index = imagecolorat($new, $x, $y);
// Only allocate a new color if not already done
if (!isset($colors[$index])) {
$rgb = imagecolorsforindex($new, $index);
if ($rgb['red'] != 255 || $rgb['green'] != 255 || $rgb['blue'] != 0) {
// If it's not the background color allocate a new color
$r = $g = 255 - $rgb['blue'];
$b = 0;
$colors[$index] = imagecolorallocate($new, $r, $g, $b);
} else {
// Otherwise set the index to false, we can ignore it
$colors[$index] = false;
}
}
// If there's something to do, do it
if ($colors[$index] !== false) {
imagesetpixel($new, $x, $y, $colors[$index]);
}
}
}
// ...
您可能还希望跟踪图像中使用的颜色,以便之后可以“清理调色板”(即,释放图像中不再使用的任何颜色,这将进一步帮助减小数据大小) 。虽然可能会更好,在这种情况下,从干净的调色板开始并检查旧的图像资源以获取像素细节,而不是将原件复制到新的图像资源。
答案 1 :(得分:0)
是的
$color = imagecolorallocate($new, 255 - $rgb['blue'], 255 - $rgb['blue'], 0);
搞乱了一切......
如果你想要相同的输出......只需将线条粘贴到外面for循环,这将解决你的问题,如果你想要特定的图像:
$color = imagecolorallocate($new, 35, 35, 0); //got from debugging
它将获得所需的输出。
DINS