yAn*_*Tar 5 php png gd alpha-transparency
我有一组图像.在此图像中存在绿色alpha颜色.我需要将透明色替换为另一种颜色(我想要替换为白色alpha颜色).
它是我的代码:
$img = imagecreatefrompng($path . $file);
$white_color_transparent = imagecolorallocatealpha($img, 255, 255, 255, 127);
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['alpha'] != 0 && $pixel_color['alpha'] != 127){
imagesetpixel($img, $x, $y, $white_color_transparent);
}
}
}
imagealphablending($img, false);
imagesavealpha($img, true);
imagepng($img, $path . $file);
Run Code Online (Sandbox Code Playgroud)
当我之前添加时,我的结果颜色与id源图像相同
imagesetpixel($img, $x, $y, $white_color_transparent);
Run Code Online (Sandbox Code Playgroud)
那条线:
imagesetpixel($img, $x, $y, $white_color);
Run Code Online (Sandbox Code Playgroud)
我只得到没有透明度的白色.
Goh*_*n67 18
没有看到你的形象,我不确定有一个简单的方法来做到这一点.
编辑2:
我在第一次编辑时注意到的一件事是它对于具有透明度的图像并不起作用,并且后面没有不透明层.
这是我尝试处理具有一定透明度的图像.正如您可以通过示例看到的那样.它完美无缺.
<?php
//These colors here are the rgba values of the green transparency I used in my test image. You will need to know this to reverse the rgb blending.
$red = 28;
$green = 198;
$blue = 72;
$alpha = .48;
$img = imagecreatefrompng('test.png');
//Adding in the image blending that Zombaya brought up. Need this so it overwrites the pixel instead of blending it
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 matches our alpha layer color, we change it white transparent
//Not sure how accurate the rounding for the alpha conversion is. Maybe the reason for the green edges in this example:
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 {
//This is the algorithm from the link. But reordered to get the old color before the transparent color went over it.
$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');
Run Code Online (Sandbox Code Playgroud)
- >原始没有透明度
- >以透明度开始图像
- >结果图片.注意绿色边缘.对于红色和绿色使用相似的不透明度,我可能会很幸运.白色部分是透明的
编辑:
我想到了更多,我遇到了这个链接:如何通过指定alpha混合量来计算RGB颜色?
这有助于我了解如何解决您的问题.虽然这取决于您是否只有一个在图像上透明的纯色.如果是梯度则更难.
<?php
//These colors here are the rgba values of the green transparency I used in my test image. You will need to know this to reverse the rgb blending.
$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);
//This is the algorithm from the link. But reordered to get the old color before the transparent color went over it.
$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');
Run Code Online (Sandbox Code Playgroud)
- 开始图像
- 图像之后
以下是上述代码中使用的rgb计算的说明.链接显示基本公式:
out = alpha * new + (1 - alpha) * old
Run Code Online (Sandbox Code Playgroud)
out 是将原稿与新颜色混合后产生的颜色.
因此我们需要重新排列公式以获得旧颜色,从而产生以下结果:
old = (out - alpha * new) / (1 - alpha)
Run Code Online (Sandbox Code Playgroud)
老答案:
为什么这条线不起作用:
$white_color_transparent = imagecolorallocatealpha($img, 255, 255, 255, 127);
Run Code Online (Sandbox Code Playgroud)
127表示完全透明,因此意味着它是不可见的.这就是结果图像与起始图像相同的原因.
为什么此行会创建一个完全白色的图像:
$white_color = imagecolorallocatealpha($img, 255, 255, 255, 0);
Run Code Online (Sandbox Code Playgroud)
要么
$white_color = imagecolorallocate($img, 255, 255, 255);
Run Code Online (Sandbox Code Playgroud)
这基本上只是在所选像素上放置一个白色像素(0表示没有透明度),这就是所选像素变为全白的原因.
现在,如果您执行以下操作:
$white_color_semi_transparent = imagecolorallocatealpha($img, 255, 255, 255, 40);
Run Code Online (Sandbox Code Playgroud)
不要用透明的白色替换透明的绿色,而是要获得浅绿色而不是半透明的白色.
看我的测试示例:
- 开始图像
- 结果图像颜色为255,255,255,40
所以这告诉我们两件事:
我不确定你是如何解决你的问题的.这取决于你的形象.我认为可以获得你想要的颜色,但显然你的图像越复杂就越难.例如,我的两个重叠的正方形有两种颜色,而不是照片.