あなたの画像を見ずに、それを行う簡単な方法があるかどうかはわかりません。
編集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');
->透明度のないオリジナル
->透明度のある画像の開始
->結果の画像。緑のエッジに注意してください。そして、私は赤と緑に同じような不透明度を使用することで幸運に恵まれたかもしれません。白い部分は透明です
編集:
私はこれについてもう少し考えて、このリンクに出くわしました:アルファブレンド量を指定することによって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');
-開始画像
-残像
上記のコードで使用されている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の結果の画像
つまり、これは2つのことを示しています。
- 1つは、基本的に既存のピクセルの色の上に色が適用されるため、透明な白ではなく明るい透明な緑になります。
- 次に、茶色の部分は影響を受けないことに注意してください。茶色の部分は、実際には緑の不透明レイヤーの下にある不透明な赤い色でした。これは、画像がフォトショップのようなレイヤーを考慮しておらず、基本的に茶色を茶色として読み取り、緑色の透明色の背後にある赤色ではないことを示しています。PNGファイルにはレイヤー情報が含まれていないため、これは理にかなっています。
問題をどのように解決するかわかりません。それはあなたのイメージに依存します。思い通りのカラーリングは可能だと思いますが、画像が複雑になるほど難しくなります。たとえば、写真とは対照的に、2つの色が重なった2つの正方形です。