PHP GD - 用 Alpha 进行颜色替换,为图像提供边框

发布于 2024-11-02 13:30:02 字数 2120 浏览 0 评论 0原文

我不确定下面的功能是否大部分有效或根本无效。我想要的是循环像素并切换颜色,同时保持 Alpha。我以为我已经可以正常工作了,直到我将页面背景设置为白色并看到图标周围有一个小边框。

我认为问题在于颜色被应用于半透明像素。因此,图像的抗锯齿部分的白色变成了浅灰色。然后我决定在设置新颜色之前使像素完全透明。这什么也没做。

所以问题来了。为什么白色图像的边框很小?

颜色转换功能。

function updateThumb($image, $newColor) {
    $img = imagecreatefrompng($image);

    $w = imagesx($img);
    $h = imagesy($img);

    // Work through pixels
    for($y=0;$y<$h;$y++) {
        for($x=0;$x<$w;$x++) {
            // Apply new color + Alpha
            $rgb = imagecolorsforindex($img, imagecolorat($img, $x, $y));

        $transparent = imagecolorallocatealpha($img, 0, 0, 0, 127);
        imagesetpixel($img, $x, $y, $transparent);

            $pixelColor = imagecolorallocatealpha($img, $newColor[0], $newColor[1], $newColor[2], $rgb['alpha']);
            imagesetpixel ($img, $x, $y, $pixelColor);
        }
    }

    // Restore Alpha
    imageAlphaBlending($img, true);
    imageSaveAlpha($img, true);

    return $img;
}

拇指需要翻转效果,因此图像是在下面的函数中制作的。我不认为这与问题有任何关系,我尝试更改上述函数来创建图像而不返回它,但同样的事情发生了。

function makeThumb($path, $top, $bottom=FALSE) {
    $width = imagesx($top);
    $height = imagesy($top);

    $thumbHeight = $bottom != FALSE ? $height * 2 : $height;

    // Create Transparent PNG
    $thumb = imagecreatetruecolor($width, $thumbHeight);
    $transparent = imagecolorallocatealpha($thumb, 0, 0, 0, 127);
    imagefill($thumb, 0, 0, $transparent);

    // Copy Top Image
    imagecopy($thumb, $top, 0, 0, 0, 0, $width, $height);

    // Copy Bottom Image
    if ($bottom != FALSE) {
        imagecopy($thumb, $bottom, 0, $height, 0, 0, $width, $height);
    }

    // Save Image with Alpha
    imageAlphaBlending($thumb, true);
    imageSaveAlpha($thumb, true);
    imagepng($thumb, $path); // save image as gif

}

函数是这样调用的...

$thumbTop = updateThumb('Path/To/Thumb', array(255,255,255));
makeThumb('output/path', $thumbTop);

这是图标: http://img171.imageshack.us /i/iconkc.png/

有什么想法吗?

I am not sure if the function below works for the most part or not at all. What i am trying to is loop through the pixels and switch the color while maintaining the alpha. I thought I had it working till I made my page background white and saw a small border around the icon.

I thought that the problem was that the color was being applied to a semi transparent pixel. Thus white turned grey into lighter grey on the anti-aliased parts of the images. I decided then to make the pixel completely transparent before setting the new color. This did nothing.

So the question. Why do white images have a small border?

The color conversion function.

function updateThumb($image, $newColor) {
    $img = imagecreatefrompng($image);

    $w = imagesx($img);
    $h = imagesy($img);

    // Work through pixels
    for($y=0;$y<$h;$y++) {
        for($x=0;$x<$w;$x++) {
            // Apply new color + Alpha
            $rgb = imagecolorsforindex($img, imagecolorat($img, $x, $y));

        $transparent = imagecolorallocatealpha($img, 0, 0, 0, 127);
        imagesetpixel($img, $x, $y, $transparent);

            $pixelColor = imagecolorallocatealpha($img, $newColor[0], $newColor[1], $newColor[2], $rgb['alpha']);
            imagesetpixel ($img, $x, $y, $pixelColor);
        }
    }

    // Restore Alpha
    imageAlphaBlending($img, true);
    imageSaveAlpha($img, true);

    return $img;
}

Thumbs need a rollover effect so the image is made in the function below. I don't believe this has anything to do with the issue, I have tried changing the above function to create the image and not return it and the same thing happens.

function makeThumb($path, $top, $bottom=FALSE) {
    $width = imagesx($top);
    $height = imagesy($top);

    $thumbHeight = $bottom != FALSE ? $height * 2 : $height;

    // Create Transparent PNG
    $thumb = imagecreatetruecolor($width, $thumbHeight);
    $transparent = imagecolorallocatealpha($thumb, 0, 0, 0, 127);
    imagefill($thumb, 0, 0, $transparent);

    // Copy Top Image
    imagecopy($thumb, $top, 0, 0, 0, 0, $width, $height);

    // Copy Bottom Image
    if ($bottom != FALSE) {
        imagecopy($thumb, $bottom, 0, $height, 0, 0, $width, $height);
    }

    // Save Image with Alpha
    imageAlphaBlending($thumb, true);
    imageSaveAlpha($thumb, true);
    imagepng($thumb, $path); // save image as gif

}

functions are called like this...

$thumbTop = updateThumb('Path/To/Thumb', array(255,255,255));
makeThumb('output/path', $thumbTop);

This is the icon: http://img171.imageshack.us/i/iconkc.png/

Any ideas?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

怂人 2024-11-09 13:30:02

天啊,谢谢你的这段代码!!!! :D 我还必须感谢其他人,但遗憾的是我在这个网站上找不到他们的代码。我拿走了你的代码和另一个人的代码并将它们合并。我注意到您保存了图像,我还没有弄清楚如何保存彩色图像,然后右键单击并通过浏览器保存,但是,图像会改变颜色。

    function updateThumb($image, $newColor) {
    $img = imagecreatefrompng($image);

    $w = imagesx($img);
    $h = imagesy($img);

    // Work through pixels
    for($y=0;$y<$h;$y++) {
        for($x=0;$x<$w;$x++) {
            // Apply new color + Alpha
            $rgb = imagecolorsforindex($img, imagecolorat($img, $x, $y));

            $transparent = imagecolorallocatealpha($img, 0, 0, 0, 127);
            imagesetpixel($img, $x, $y, $transparent);


            // Here, you would make your color transformation.
            $red_set=$newColor[0]/100*$rgb['red'];
            $green_set=$newColor[1]/100*$rgb['green'];
            $blue_set=$newColor[2]/100*$rgb['blue'];
            if($red_set>255)$red_set=255;
            if($green_set>255)$green_set=255;
            if($blue_set>255)$blue_set=255;

            $pixelColor = imagecolorallocatealpha($img, $red_set, $green_set, $blue_set, $rgb['alpha']);
            imagesetpixel ($img, $x, $y, $pixelColor);
        }
    }

    // Restore Alpha
    imageAlphaBlending($img, true);
    imageSaveAlpha($img, true);

    return $img;
}

function makeThumb($path, $top, $bottom=FALSE) {
    $width = imagesx($top);
    $height = imagesy($top);

    $thumbHeight = $bottom != FALSE ? $height * 2 : $height;

    // Create Transparent PNG
    $thumb = imagecreatetruecolor($width, $thumbHeight);
    $transparent = imagecolorallocatealpha($thumb, 0, 0, 0, 127);
    imagefill($thumb, 0, 0, $transparent);

    // Copy Top Image
    imagecopy($thumb, $top, 0, 0, 0, 0, $width, $height);

    // Copy Bottom Image
    if ($bottom != FALSE) {
        imagecopy($thumb, $bottom, 0, $height, 0, 0, $width, $height);
    }

    // Save Image with Alpha
    imageAlphaBlending($thumb, true);
    imageSaveAlpha($thumb, true);
    header('Content-Type: image/png');
    imagepng($thumb, $path); // save image as png

}

$thumbTop = updateThumb('input/path', array(240,105,15));
makeThumb('output/path', $thumbTop);

OMG THANK YOU FOR THIS BIT OF CODE!!!! :D There is somone else i have to thank also, but I cannot find their code on this site sadly. I took, your code and the other guy's code and merged them. I've noticed that you save the image, I haven't figured out how to saved the colored image other then right click and save via the browser, however, the image will change color.

    function updateThumb($image, $newColor) {
    $img = imagecreatefrompng($image);

    $w = imagesx($img);
    $h = imagesy($img);

    // Work through pixels
    for($y=0;$y<$h;$y++) {
        for($x=0;$x<$w;$x++) {
            // Apply new color + Alpha
            $rgb = imagecolorsforindex($img, imagecolorat($img, $x, $y));

            $transparent = imagecolorallocatealpha($img, 0, 0, 0, 127);
            imagesetpixel($img, $x, $y, $transparent);


            // Here, you would make your color transformation.
            $red_set=$newColor[0]/100*$rgb['red'];
            $green_set=$newColor[1]/100*$rgb['green'];
            $blue_set=$newColor[2]/100*$rgb['blue'];
            if($red_set>255)$red_set=255;
            if($green_set>255)$green_set=255;
            if($blue_set>255)$blue_set=255;

            $pixelColor = imagecolorallocatealpha($img, $red_set, $green_set, $blue_set, $rgb['alpha']);
            imagesetpixel ($img, $x, $y, $pixelColor);
        }
    }

    // Restore Alpha
    imageAlphaBlending($img, true);
    imageSaveAlpha($img, true);

    return $img;
}

function makeThumb($path, $top, $bottom=FALSE) {
    $width = imagesx($top);
    $height = imagesy($top);

    $thumbHeight = $bottom != FALSE ? $height * 2 : $height;

    // Create Transparent PNG
    $thumb = imagecreatetruecolor($width, $thumbHeight);
    $transparent = imagecolorallocatealpha($thumb, 0, 0, 0, 127);
    imagefill($thumb, 0, 0, $transparent);

    // Copy Top Image
    imagecopy($thumb, $top, 0, 0, 0, 0, $width, $height);

    // Copy Bottom Image
    if ($bottom != FALSE) {
        imagecopy($thumb, $bottom, 0, $height, 0, 0, $width, $height);
    }

    // Save Image with Alpha
    imageAlphaBlending($thumb, true);
    imageSaveAlpha($thumb, true);
    header('Content-Type: image/png');
    imagepng($thumb, $path); // save image as png

}

$thumbTop = updateThumb('input/path', array(240,105,15));
makeThumb('output/path', $thumbTop);
我早已燃尽 2024-11-09 13:30:02

谢谢你!你启发我在我正在构建的图像工作者中使用逐像素的方式。
起初我遇到了与您相同的问题,但我想我找到了解决方法。

问题

在我看来好像imagesetpixel没有用新的rgba值替换像素,而是将它们放在旧的之上。

解决方案

function updateThumb($image, $newColor) {
    $img = imagecreatefrompng($image);

    $w = imagesx($img);
    $h = imagesy($img);

    // create a new blank image.
    $target = imagecreatetruecolor($w, $h);
    $transparent = imagecolorallocatealpha($target, 0, 0, 0, 127);
    imagefill($target, 0, 0, $transparent);

    // Work through pixels
    for($y=0;$y<$h;$y++) {
        for($x=0;$x<$w;$x++) {
            // Apply new color + Alpha
            $rgb = imagecolorsforindex($img, imagecolorat($img, $x, $y));

            // and set the new color to the blank image.
            $pixelColor = imagecolorallocatealpha($target, $newColor[0], $newColor[1], $newColor[2], $rgb['alpha']);
            imagesetpixel($target, $x, $y, $pixelColor);
        }
    }

    // Restore Alpha
    imageAlphaBlending($target, true);
    imageSaveAlpha($target, true);

    return $target;
}

出了什么问题:

// new image
$target = imagecreatetruecolor(1, 1);

// Set a Pixel
$pixelColor = imagecolorallocatealpha($target, 0, 0, 0, 60);
imagesetpixel($target, 0, 0, $pixelColor);

// "Replace" The Pixel
$pixelColor = imagecolorallocatealpha($target, 255, 255, 255, 60);
imagesetpixel($target, 0, 0, $pixelColor);

// See the rgba values of the pixel
var_dump(imagecolorsforindex($target, imagecolorat($target, 0, 0)));

预期:

array(4) {  
    ["red"]=> int(255)  
    ["green"]=> int(255)  
    ["blue"]=> int(255)  
    ["alpha"]=> int(60)  
}

实际:

array(4) {  
    ["red"]=> int(174)  
    ["green"]=> int(174)  
    ["blue"]=> int(174)  
    ["alpha"]=> int(28)  
} 

Thank you for this! You inspired me to use a pixel by pixel way in an image worker i'm building.
At first i had the same problem you had but i think i figured out how to fix it.

Problem

it seems to me as if imagesetpixel does not replace the pixel with the new rgba values but instead puts them OVER the old ones.

Solution

function updateThumb($image, $newColor) {
    $img = imagecreatefrompng($image);

    $w = imagesx($img);
    $h = imagesy($img);

    // create a new blank image.
    $target = imagecreatetruecolor($w, $h);
    $transparent = imagecolorallocatealpha($target, 0, 0, 0, 127);
    imagefill($target, 0, 0, $transparent);

    // Work through pixels
    for($y=0;$y<$h;$y++) {
        for($x=0;$x<$w;$x++) {
            // Apply new color + Alpha
            $rgb = imagecolorsforindex($img, imagecolorat($img, $x, $y));

            // and set the new color to the blank image.
            $pixelColor = imagecolorallocatealpha($target, $newColor[0], $newColor[1], $newColor[2], $rgb['alpha']);
            imagesetpixel($target, $x, $y, $pixelColor);
        }
    }

    // Restore Alpha
    imageAlphaBlending($target, true);
    imageSaveAlpha($target, true);

    return $target;
}

What went wrong:

// new image
$target = imagecreatetruecolor(1, 1);

// Set a Pixel
$pixelColor = imagecolorallocatealpha($target, 0, 0, 0, 60);
imagesetpixel($target, 0, 0, $pixelColor);

// "Replace" The Pixel
$pixelColor = imagecolorallocatealpha($target, 255, 255, 255, 60);
imagesetpixel($target, 0, 0, $pixelColor);

// See the rgba values of the pixel
var_dump(imagecolorsforindex($target, imagecolorat($target, 0, 0)));

Expected:

array(4) {  
    ["red"]=> int(255)  
    ["green"]=> int(255)  
    ["blue"]=> int(255)  
    ["alpha"]=> int(60)  
}

Actual:

array(4) {  
    ["red"]=> int(174)  
    ["green"]=> int(174)  
    ["blue"]=> int(174)  
    ["alpha"]=> int(28)  
} 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文