如果没有看到你的图像,我不确定有没有容易的方法可以做到这一点。
编辑2:
我从我的第一个编辑中注意到一件事情,那就是它对于具有透明度并且没有不透明层的图像不起作用。
这是我尝试处理具有一些透明度的图像的方式。正如你可以从示例中看到的那样。它并没有完美地解决问题。
<?php
$red = 28;
$green = 198;
$blue = 72;
$alpha = .48;
$img = imagecreatefrompng('test.png');
imagealphablending($img, false);
for ($y = 0; $y < imagesy($img); $y++) {
for ($x = 0; $x < imagesx($img); $x++) {
$rgb = imagecolorat($img, $x, $y);
$pixel_color = imagecolorsforindex($img, $rgb);
if($pixel_color['red'] == $red &&
$pixel_color['green'] == $green &&
$pixel_color['blue'] == $blue &&
$pixel_color['alpha'] == round(127 - ($alpha * 127))){
$color = imagecolorallocatealpha($img, 255, 255, 255, 127);
} else {
$oldR = ($pixel_color['red'] - $alpha * $red) / (1 - $alpha);
$oldG = ($pixel_color['green'] - $alpha * $green ) / (1 - $alpha);
$oldB = ($pixel_color['blue'] - $alpha * $blue) / (1 - $alpha);
$color = imagecolorallocatealpha($img, $oldR, $oldG, $oldB, $pixel_color['alpha']);
}
imagesetpixel($img, $x, $y, $color);
}
}
imagesavealpha($img, true);
imagepng($img, 'test_result.png');
-> 原始图像(无透明度)
-> 以透明度开始的图像
-> 生成的图像。请注意绿色边缘。我可能会很幸运地使用相似的不透明度来表示红色和绿色。白色部分是透明的
编辑:
我考虑了一些,并遇到了这个链接:如何通过指定alpha混合量计算RGB颜色?
这帮助我理解如何解决你的问题。尽管这取决于您是否只有一个在图像上透明的实心颜色。如果是渐变则更加困难。
<?php
$red = 44;
$green = 215;
$blue = 56;
$alpha = .45;
$img = imagecreatefrompng('test2.png');
for ($y = 0; $y < imagesy($img); $y++) {
for ($x = 0; $x < imagesx($img); $x++) {
$rgb = imagecolorat($img, $x, $y);
$pixel_color = imagecolorsforindex($img, $rgb);
$oldR = ($pixel_color['red'] - $alpha * $red) / (1 - $alpha);
$oldG = ($pixel_color['green'] - $alpha * $green ) / (1 - $alpha);
$oldB = ($pixel_color['blue'] - $alpha * $blue) / (1 - $alpha);
$color = imagecolorallocate($img, $oldR, $oldG, $oldB);
imagesetpixel($img, $x, $y, $color);
}
}
imagesavealpha($img, true);
imagepng($img, 'test_result.png');
- 起始图像
- 改变后的图像
上面代码中使用的rgb计算方法的解释如下。链接显示了基本公式:
out = alpha * new + (1 - alpha) * old
out
是原始颜色与新颜色混合后的结果颜色。
因此,我们需要重新排列公式以获得旧颜色,具体如下:
old = (out - alpha * new) / (1 - alpha)
旧答案:
为什么这行代码不起作用:
$white_color_transparent = imagecolorallocatealpha($img, 255, 255, 255, 127)
127表示完全透明,这意味着它是不可见的。这就是为什么结果图像与起始图像相同的原因。
为什么这行代码会创建一个完全白色的图像:
$white_color = imagecolorallocatealpha($img, 255, 255, 255, 0)
或者
$white_color = imagecolorallocate($img, 255, 255, 255)
这基本上只是在所选像素上放置一个白色像素(0表示无透明度),这就是为什么所选像素变成完全白色的原因。
现在,如果你执行以下操作:
$white_color_semi_transparent = imagecolorallocatealpha($img, 255, 255, 255, 40);
不要用半透明的白色替换透明的绿色,现在你得到了一种浅绿色而不是半透明的白色。
看我的测试例子:
- 开始的图像
- 具有颜色255,255,255,40的结果图像
所以这告诉我们两件事:
- 首先是颜色基本上是应用在现有像素的颜色之上的,因此变成了浅的透明绿色而不是透明的白色。
- 其次,请注意,棕色部分没有受到影响。棕色部分实际上是在绿色不透明层下面的不透明红色颜色。这说明图像没有考虑像Photoshop那样的图层,基本上将棕色颜色读作棕色,而不是在绿色透明颜色后面的红色颜色。这是有道理的,因为PNG文件不带有图层信息。
我不确定如何解决您的问题。这取决于您的图像。我认为可以获得所需的着色,但是对于比如我的两个有两种颜色的重叠正方形与一张照片之类的更复杂的图像来说,它显然会更加困难。