我可以使用 PHP 中的 GD 库交换图像中的颜色吗?

发布于 2024-07-12 05:42:24 字数 353 浏览 11 评论 0原文

我得到了这样的图像(它是一个图表):

黄金交易图
(来源:kitconet.com

我想改变颜色,所以白色是黑色,图形线是浅蓝色等。可以用GD和PHP实现吗?

I got the image like this (it's a graph):

Gold Trade Graph
(source: kitconet.com)

I want to change the colours, so the white is black, the graph line is light blue, etc.. is it possible to achieve with GD and PHP?

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

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

发布评论

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

评论(8

月下伊人醉 2024-07-19 05:42:24

这会将白色替换为灰色

$imgname = "test.gif";
$im = imagecreatefromgif ($imgname);

$index = imagecolorclosest ( $im,  255,255,255 ); // get White COlor
imagecolorset($im,$index,92,92,92); // SET NEW COLOR

$imgname = "result.gif";
imagegif($im, $imgname ); // save image as gif
imagedestroy($im);

在此处输入图像描述

This will replace the white color with Gray

$imgname = "test.gif";
$im = imagecreatefromgif ($imgname);

$index = imagecolorclosest ( $im,  255,255,255 ); // get White COlor
imagecolorset($im,$index,92,92,92); // SET NEW COLOR

$imgname = "result.gif";
imagegif($im, $imgname ); // save image as gif
imagedestroy($im);

enter image description here

笙痞 2024-07-19 05:42:24

我在使这个解决方案发挥作用时遇到了麻烦。 该图像不能是真彩色图像。 首先使用 imagetruecolortopalette() 进行转换;

$imgname = "test.gif";
$im = imagecreatefromgif ($imgname);

imagetruecolortopalette($im,false, 255);

$index = imagecolorclosest ( $im,  255,255,255 ); // get White COlor
imagecolorset($im,$index,92,92,92); // SET NEW COLOR

$imgname = "result.gif";
imagegif($im, $imgname ); // save image as gif
imagedestroy($im);

I had trouble making this solution work. The image cannot be a true color image. Convert it first with imagetruecolortopalette();

$imgname = "test.gif";
$im = imagecreatefromgif ($imgname);

imagetruecolortopalette($im,false, 255);

$index = imagecolorclosest ( $im,  255,255,255 ); // get White COlor
imagecolorset($im,$index,92,92,92); // SET NEW COLOR

$imgname = "result.gif";
imagegif($im, $imgname ); // save image as gif
imagedestroy($im);
橘亓 2024-07-19 05:42:24

我知道这已经晚了,而且是事后发生的,但我已经编写了一个脚本,可以在更大的范围内完成此任务。 希望看到这篇文章的人可以使用它。 它需要许多单色图层的源图像(您的选择)。 您为其提供源颜色和每层的色调,脚本将返回专门根据您提供的十六进制代码着色的合成图像(具有完全透明度)。

查看下面的代码。 更详细的解释可以在我的 博客

function hexLighter($hex, $factor = 30) {
    $new_hex = '';

    $base['R'] = hexdec($hex{0}.$hex{1});
    $base['G'] = hexdec($hex{2}.$hex{3});
    $base['B'] = hexdec($hex{4}.$hex{5});

    foreach ($base as $k => $v) {
        $amount = 255 - $v;
        $amount = $amount / 100;
        $amount = round($amount * $factor);
        $new_decimal = $v + $amount;

        $new_hex_component = dechex($new_decimal);

        $new_hex .= sprintf('%02.2s', $new_hex_component);
    }

    return $new_hex;
}

// Sanitize/Validate provided color variable
if (!isset($_GET['color']) || strlen($_GET['color']) != 6) {
    header($_SERVER['SERVER_PROTOCOL'] . ' 400 Bad Request', true, 400);

    exit(0);
}

if (file_exists( "cache/{$_GET['color']}.png" )) {
    header( 'Content-Type: image/png' );
    readfile( "cache/{$_GET['color']}.png" );

    exit(0);
}

// Desired final size of image
$n_width = 50;
$n_height = 50;

// Actual size of source images
$width = 125;
$height = 125;

$image =    imagecreatetruecolor($width, $height);
            imagesavealpha($image, true);
            imagealphablending($image, false);

$n_image =  imagecreatetruecolor($n_width, $n_height);
            imagesavealpha($n_image, true);
            imagealphablending($n_image, false);

$black = imagecolorallocate($image, 0, 0, 0);
$transparent = imagecolorallocatealpha($image, 255, 255, 255, 127);

imagefilledrectangle($image, 0, 0, $width, $height, $transparent);

$layers = array();
$layers_processed = array();

$layers[] = array( 'src' => 'layer01.gif', 'level' => 0 );  // Border
$layers[] = array( 'src' => 'layer02.gif', 'level' => 35 );     // Background
$layers[] = array( 'src' => 'layer03.gif', 'level' => 100 );    // White Quotes

foreach ($layers as $idx => $layer) {
    $img = imagecreatefromgif( $layer['src'] );
    $processed = imagecreatetruecolor($width, $height);

    imagesavealpha($processed, true);
    imagealphablending($processed, false);

    imagefilledrectangle($processed, 0, 0, $width, $height, $transparent);

    $color = hexLighter( $_GET['color'], $layer['level'] );
    $color = imagecolorallocate($image,
        hexdec( $color{0} . $color{1} ),
        hexdec( $color{2} . $color{3} ),
        hexdec( $color{4} . $color{5} )
    );

    for ($x = 0; $x < $width; $x++)
        for ($y = 0; $y < $height; $y++)
            if ($black === imagecolorat($img, $x, $y))
                imagesetpixel($processed, $x, $y, $color);

    imagecolortransparent($processed, $transparent);
    imagealphablending($processed, true);

    array_push($layers_processed, $processed);

    imagedestroy( $img );
}

foreach ($layers_processed as $processed) {
    imagecopymerge($image, $processed, 0, 0, 0, 0, $width, $height, 100);

    imagedestroy( $processed );
}

imagealphablending($image, true);

imagecopyresampled($n_image, $image, 0, 0, 0, 0, $n_width, $n_height, $width, $height);

imagealphablending($n_image, true);

header( 'Content-Type: image/png' );
imagepng( $n_image, "cache/{$_GET['color']}.png" );
imagepng( $n_image );

// Free up memory
imagedestroy( $n_image );
imagedestroy( $image );

I know this is late and after the fact, but I've put together a script that will do this on a slightly larger scale. Hopefully someone who comes across this post can use it. It takes an number of source images that are one-color layers (your choice). You provide it with a source color and the tint of each layer and the script returns a composite image (with full transparency) colored specifically to your provided hex code.

Check out the code below. A more detailed explanation can be found on my blog.

function hexLighter($hex, $factor = 30) {
    $new_hex = '';

    $base['R'] = hexdec($hex{0}.$hex{1});
    $base['G'] = hexdec($hex{2}.$hex{3});
    $base['B'] = hexdec($hex{4}.$hex{5});

    foreach ($base as $k => $v) {
        $amount = 255 - $v;
        $amount = $amount / 100;
        $amount = round($amount * $factor);
        $new_decimal = $v + $amount;

        $new_hex_component = dechex($new_decimal);

        $new_hex .= sprintf('%02.2s', $new_hex_component);
    }

    return $new_hex;
}

// Sanitize/Validate provided color variable
if (!isset($_GET['color']) || strlen($_GET['color']) != 6) {
    header($_SERVER['SERVER_PROTOCOL'] . ' 400 Bad Request', true, 400);

    exit(0);
}

if (file_exists( "cache/{$_GET['color']}.png" )) {
    header( 'Content-Type: image/png' );
    readfile( "cache/{$_GET['color']}.png" );

    exit(0);
}

// Desired final size of image
$n_width = 50;
$n_height = 50;

// Actual size of source images
$width = 125;
$height = 125;

$image =    imagecreatetruecolor($width, $height);
            imagesavealpha($image, true);
            imagealphablending($image, false);

$n_image =  imagecreatetruecolor($n_width, $n_height);
            imagesavealpha($n_image, true);
            imagealphablending($n_image, false);

$black = imagecolorallocate($image, 0, 0, 0);
$transparent = imagecolorallocatealpha($image, 255, 255, 255, 127);

imagefilledrectangle($image, 0, 0, $width, $height, $transparent);

$layers = array();
$layers_processed = array();

$layers[] = array( 'src' => 'layer01.gif', 'level' => 0 );  // Border
$layers[] = array( 'src' => 'layer02.gif', 'level' => 35 );     // Background
$layers[] = array( 'src' => 'layer03.gif', 'level' => 100 );    // White Quotes

foreach ($layers as $idx => $layer) {
    $img = imagecreatefromgif( $layer['src'] );
    $processed = imagecreatetruecolor($width, $height);

    imagesavealpha($processed, true);
    imagealphablending($processed, false);

    imagefilledrectangle($processed, 0, 0, $width, $height, $transparent);

    $color = hexLighter( $_GET['color'], $layer['level'] );
    $color = imagecolorallocate($image,
        hexdec( $color{0} . $color{1} ),
        hexdec( $color{2} . $color{3} ),
        hexdec( $color{4} . $color{5} )
    );

    for ($x = 0; $x < $width; $x++)
        for ($y = 0; $y < $height; $y++)
            if ($black === imagecolorat($img, $x, $y))
                imagesetpixel($processed, $x, $y, $color);

    imagecolortransparent($processed, $transparent);
    imagealphablending($processed, true);

    array_push($layers_processed, $processed);

    imagedestroy( $img );
}

foreach ($layers_processed as $processed) {
    imagecopymerge($image, $processed, 0, 0, 0, 0, $width, $height, 100);

    imagedestroy( $processed );
}

imagealphablending($image, true);

imagecopyresampled($n_image, $image, 0, 0, 0, 0, $n_width, $n_height, $width, $height);

imagealphablending($n_image, true);

header( 'Content-Type: image/png' );
imagepng( $n_image, "cache/{$_GET['color']}.png" );
imagepng( $n_image );

// Free up memory
imagedestroy( $n_image );
imagedestroy( $image );
×眷恋的温暖 2024-07-19 05:42:24

I haven't tried it myself but you can look at the function imagecolorset() in the GD library It does a color fill like effect, that could help with the white background.

烟雨凡馨 2024-07-19 05:42:24

您可以尝试 imagefilter 函数 http://lv.php.net/imagefilter - 但这不会让您可以直接将一种颜色替换为另一种颜色,只需更改 r/g/b 组件即可。

可以使用 imagesetpixel http://nl2.php.net/imagesetpixel 实现非常低级别的解决方案设置新的像素值。

You could try the imagefilter function http://lv.php.net/imagefilter - but that will not give your direct access to replace one color with another, just changing the r/g/b components.

A very low level solution could be implemented using imagesetpixel http://nl2.php.net/imagesetpixel to set the new pixel values.

棒棒糖 2024-07-19 05:42:24

IMG_FILTER_NEGATE:反转图像的所有颜色。

http://www.php.net/manual/en/function.imagefilter.php

这可能是一个解决方案吗?

IMG_FILTER_NEGATE: Reverses all colors of the image.

http://www.php.net/manual/en/function.imagefilter.php

Could that be a solution?

那支青花 2024-07-19 05:42:24

缓慢但可靠的方法,迭代每个像素。

function ReplaceColour($img, $r1, $g1, $b1, $r2, $g2, $b2)
{
    if(!imageistruecolor($img))
        imagepalettetotruecolor($img);
    $col1 = (($r1 & 0xFF) << 16) + (($g1 & 0xFF) << 8) + ($b1 & 0xFF);
    $col2 = (($r2 & 0xFF) << 16) + (($g2 & 0xFF) << 8) + ($b2 & 0xFF);

    $width = imagesx($img); 
    $height = imagesy($img);
    for($x=0; $x < $width; $x++)
        for($y=0; $y < $height; $y++)
        {
            $colrgb = imagecolorat($img, $x, $y);
            if($col1 !== $colrgb)
                continue; 
            imagesetpixel ($img, $x , $y , $col2);
        }   
}

The slow but sure approach, iterating over every pixel.

function ReplaceColour($img, $r1, $g1, $b1, $r2, $g2, $b2)
{
    if(!imageistruecolor($img))
        imagepalettetotruecolor($img);
    $col1 = (($r1 & 0xFF) << 16) + (($g1 & 0xFF) << 8) + ($b1 & 0xFF);
    $col2 = (($r2 & 0xFF) << 16) + (($g2 & 0xFF) << 8) + ($b2 & 0xFF);

    $width = imagesx($img); 
    $height = imagesy($img);
    for($x=0; $x < $width; $x++)
        for($y=0; $y < $height; $y++)
        {
            $colrgb = imagecolorat($img, $x, $y);
            if($col1 !== $colrgb)
                continue; 
            imagesetpixel ($img, $x , $y , $col2);
        }   
}
情绪 2024-07-19 05:42:24

我不知道有任何现成的功能。 但我想你可以遍历图像的每个像素并改变它的颜色......

I'm not aware of any ready-made functions. But I suppose you could go trough every pixel of the image and change it's colour...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文