且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

Php - 替换透明png图像的基色

更新时间:2023-11-10 20:39:40

这段代码并不能说明这个问题,而是改变了颜色:





使用ALPHA通道的图像来确定着色。对于其他结果,只需使用 imagecolorallocatealpha()

  colorizeBasedOnAplhaChannnel($ file,$ targetR,$ targetG,$ targetB,$ targetName){

$ im_src = imagecreatefrompng($ file);

$ width = imagesx($ im_src);
$ height = imagesy($ im_src);

$ im_dst = imagecreatefrompng($ file);

//注意:
//让图像中的颜色数减少到一个
imagefilledrectangle($ im_dst,0,0,$ width,$ height,0xFFFFFF );

for($ x = 0; $ x< $ width; $ x ++){
for($ y = 0; $ y< $ height; $ y ++){

$ alpha =(imagecolorat($ im_src,$ x,$ y)> 24& 0xFF);

$ col = imagecolorallocatealpha($ im_dst,
$ targetR - (int)(1.0 / 255.0 * $ alpha *(double)$ targetR),
$ targetG - )(1.0 / 255.0 * $ alpha *(double)$ targetB),
$ targetB - (int)(1.0 / 255.0 * $ alpha * b);

if(false === $ col){
die('sorry,out of colors ...');
}

imagesetpixel($ im_dst,$ x,$ y,$ col);

}

}

imagepng($ im_dst,$ targetName);
imagedestroy($ im_dst);

}

unlink(dirname(__FILE__)。'/newleaf.png');
unlink(dirname(__FILE__)。'/newleaf1.png');
unlink(dirname(__FILE__)。'/newleaf2.png');

$ img = dirname(__FILE__)。 '/leaf.png';
colorizeBasedOnAplhaChannnel($ img,0,0,0xFF,'newleaf1.png');
colorizeBasedOnAplhaChannnel($ img,0xFF,0,0xFF,'newleaf2.png');
?>

原始
< img src =leaf.png>
< br />
< img src =newleaf1.png>
< br />
< img src =newleaf2.png>


I have searched a lot and I found only few solutions (on google and *** so please don't mark this one as a duplicate unless there's really duplicate question), but problems are hard edges. Is there any proper way of changing base color of, let's say black shape png image with transparent background but to preserve soft edges?

This is an example image:

I want it to look like this:

but the solutions I found give me this one:

Since I will be using this on my localhost, only for personal use, any php library that could help achieve this is appreciated.

UPDATE:

This is the function that gives me 3rd image:

function LoadPNG($imgname)
{
    $im = imagecreatefrompng ($imgname);
    imagetruecolortopalette($im,false, 255);
    $index = imagecolorclosest ( $im,  0,0,0 ); // GET BLACK COLOR
    imagecolorset($im,$index,0,150,255); // SET COLOR TO BLUE
    $name = basename($imgname);
    imagepng($im, getcwd()."/tmp/$name" ); // save image as png
    imagedestroy($im);
}
$dir = getcwd()."/img/";
$images = glob($dir."/*.png",GLOB_BRACE);
foreach($images as $image) {
    LoadPNG($image);
}

Originally, this function was a solution for GIF images (palette of 255 colors) so I guess that's why there are hard edges. I am looking for a solution (improvement to this script) to preserve transparency and soft edges of PNG image.

EDIT 2:

I have found an interesting approach using html5 canvas and javascript here: http://users7.jabry.com/overlord/mug.html

Maybe someone could have an idea how to translate this into PHP if even possible.

NEW SOLUTION

In answers

This code doesn't exemplify the problem, but transforms colors like this:

Uses the ALPHA channel of an image to determines coloring. For other results, just play around with imagecolorallocatealpha():

function colorizeBasedOnAplhaChannnel( $file, $targetR, $targetG, $targetB, $targetName ) {

    $im_src = imagecreatefrompng( $file );

    $width = imagesx($im_src);
    $height = imagesy($im_src);

    $im_dst = imagecreatefrompng( $file );

    // Note this:
    // Let's reduce the number of colors in the image to ONE
    imagefilledrectangle( $im_dst, 0, 0, $width, $height, 0xFFFFFF );

    for( $x=0; $x<$width; $x++ ) {
        for( $y=0; $y<$height; $y++ ) {

            $alpha = ( imagecolorat( $im_src, $x, $y ) >> 24 & 0xFF );

            $col = imagecolorallocatealpha( $im_dst,
                $targetR - (int) ( 1.0 / 255.0  * $alpha * (double) $targetR ),
                $targetG - (int) ( 1.0 / 255.0  * $alpha * (double) $targetG ),
                $targetB - (int) ( 1.0 / 255.0  * $alpha * (double) $targetB ),
                $alpha
                );

            if ( false === $col ) {
                die( 'sorry, out of colors...' );
            }

            imagesetpixel( $im_dst, $x, $y, $col );

        }

    }

    imagepng( $im_dst, $targetName);
    imagedestroy($im_dst);

}

unlink( dirname ( __FILE__ ) . '/newleaf.png' );
unlink( dirname ( __FILE__ ) . '/newleaf1.png' );
unlink( dirname ( __FILE__ ) . '/newleaf2.png' );

$img = dirname ( __FILE__ ) . '/leaf.png';
colorizeBasedOnAplhaChannnel( $img, 0, 0, 0xFF, 'newleaf1.png' );
colorizeBasedOnAplhaChannnel( $img, 0xFF, 0, 0xFF, 'newleaf2.png' );
?>

Original
<img src="leaf.png">
<br />
<img src="newleaf1.png">
<br />
<img src="newleaf2.png">