gpt4 book ai didi

php - 在PHP中替换透明色

转载 作者:可可西里 更新时间:2023-11-01 13:35:53 26 4
gpt4 key购买 nike

我有一组图像。在此图像中存在绿色 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);

当我在之前添加时,我的结果颜色与 id 源图像相同

imagesetpixel($img, $x, $y, $white_color_transparent);

那一行:

imagesetpixel($img, $x, $y, $white_color);

我只得到没有透明度的白色。

最佳答案

没有看到您的图片,我不确定是否有简单的方法来做到这一点。

编辑 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');

enter image description here -> 原件不透明

enter image description here -> 具有透明度的起始图像

enter image description here -> 结果图像。注意绿色边缘。我可能很幸运对红色和绿色使用了类似的不透明度。白色部分是透明的

编辑:

我仔细考虑了一下,发现了这个链接:How to calculate an RGB colour by specifying an alpha blending amount?

这帮助我了解了如何解决您的问题。尽管这取决于您是否只有在图像上透明的纯色。如果是渐变,那就更难了。

<?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');

enter image description here - 起始图像

enter image description here - 后图像

这里是对上面代码中使用的 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); 

不是用透明的白色代替透明的绿色,而是用浅绿色代替半透明的白色。

查看我的测试示例:

Starting Image - 起始图像

enter image description here - 结果图像颜色为 255,255,255,40

所以这告诉我们两件事:

  1. 首先是颜色基本上应用在现有像素颜色之上,因此更浅的透明绿色而不是透明白色。
  2. 其次,注意棕色部分没有受到影响。棕色部分实际上是绿色不透明层下面的不透明红色。这说明图像没有考虑像 photoshop 这样的图层,基本上将棕色读为棕色,而不是绿色透明色后面的红色。这是有道理的,因为 PNG 文件不附带图层信息。

我不确定你会如何解决你的问题。这取决于你的形象。我认为有可能得到你想要的颜色,但显然你的图像越复杂就越困难。例如,我的两个具有两种颜色的重叠正方形与说一张照片。

关于php - 在PHP中替换透明色,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10246249/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com