如何获得具有 GD 的像素的正确 rgb 值?

Posted

技术标签:

【中文标题】如何获得具有 GD 的像素的正确 rgb 值?【英文标题】:How do I get the correct rgb value for a pixel with GD? 【发布时间】:2014-10-27 11:49:39 【问题描述】:

我有一个 4x1 像素的 png,其中最左边的像素是白色 (#ffffff),第二个像素是红色 (#ff0000),第三个像素是绿色 (#00ff00),最右边的像素是蓝色 (#0000ff ),在这里几乎看不见:.

使用以下 perl 脚本,我尝试读取每个像素的 rgb 值:

use warnings;
use strict;

use GD;

my $image = new GD::Image('white-red-green-blue.png') or die;

for (my $x=0; $x<4; $x++) 
  my $index = $image->getPixel($x, 0);
  my ($r,$g,$b) = $image->rgb($index);

  printf "%3d %3d %3d\n", $r, $g, $b;

令我惊讶的是,它打印出来了

252 254 252
252   2   4
  4 254   4
  4   2 252

没想到

255 255 255
255   0   0
  0 255   0
  0   0 255

为什么脚本会报告错误的 rgb 值,我该如何教它报告正确的值?

编辑根据 mpapec 的问题,base64 white-red-green-blue.png 的输出是

iVBORw0KGgoAAAANSUhEUgAAAAQAAAABCAIAAAB2XpiaAAAAAXNSR0IArs4c6QAAAARnQU1B
AACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAASSURBVBhXY/gPBAwMDEDM8B8AL90F
+8V5iZQAAAAASUVORK5CYII=

Edit II 根据 dgw 的建议,我也尝试了my $image = newFromPng GD::Image('white-red-green-blue.png') or die;,但结果相同。

更新:我用Image::Magick而不是GD尝试了同样的事情:

use warnings;
use strict;

use Image::Magick;

my $image = Image::Magick->new or die;
my $read = $image -> Read('white-red-green-blue.png');

for (my $x=0; $x<4; $x++) 

  my @pixels = $image->GetPixels(
      width     => 1,
      height    => 1,
      x         => $x,
      y         => 0,
      map       =>'RGB',
      #normalize => 1
  );

  printf "%3d %3d %3d\n", $pixels[0] / 256, $pixels[1] / 256, $pixels[2] / 256;


而且,不出所料,它会打印出预期的内容

255 255 255
255   0   0
  0 255   0
  0   0 255

【问题讨论】:

你试过用newFromPng代替new吗? 【参考方案1】:

更新

好的,如果你这样做,它可以很好地处理你的图像:

GD::Image->trueColor(1);

在使用 GD 开始任何事情之前。我认为这是因为一个图像是调色板,而另一个不是。见这里:

原答案

它在我的 iMac 上运行良好。我用 ImageMagick 生成了这样的图像:

convert -size 1x1! xc:rgb\(255,255,255\) xc:rgb\(255,0,0\) xc:rgb\(0,255,0\) xc:rgb\(0,0,255\) +append wrgb.png

./go.pl
255 255 255
255   0   0
0 255   0
0   0 255

我怀疑您的图像生成不正确。

【讨论】:

请再看看——我想我已经破解了。 GD::Image-&gt;trueColor(1); 成功了。非常感谢! @RenéNyffenegger 这很有趣,但仍然存在这样一个事实,即您可以在调色板中拥有“纯”颜色而无需诉诸trueColor【参考方案2】:

您的源图像不是您所期望的纯 RGB,但您可以根据需要生成一个,

use warnings;
use strict;

use GD;

my $image = new GD::Image('white-red-green-blue.png') or die;
my @c = (
  [255,255,255],
  [255,0,0],
  [0,255,0],
  [0,0,255],
);
for my $x (0 .. 3) 
  ##
  $image->setPixel(
    $x,0, $image->colorAllocate(@ $c[$x] )
  );
  ##
  my $index = $image->getPixel($x, 0);
  my ($r,$g,$b) = $image->rgb($index);

  printf "%3d %3d %3d\n", $r, $g, $b;

输出

255 255 255
255   0   0
  0 255   0
  0   0 255

echo 'iVBORw0KGgoAAAANSUhEUgAAAAQAAAABBAMAAAALEhL+AAAAGFBMVEUEAvwE/gT8AgT8/vz/////
AAAA/wAAAP/i4quSAAAAC0lEQVQImWNwTQcAAPQArQCZcI0AAAAASUVORK5CYII=' |
base64 -d > new.png

【讨论】:

问题是:如果我用图像程序打开我的“不那么纯的图像”并使用“移液器”选择颜色,颜色纯的(255 /255/255 等)。我真的不明白这里发生了什么。 @RenéNyffenegger 我会质疑你的图像程序。 new.png 应该在 perl 和 'pipette' 中给出相同的 RGB 结果。 尝试发布您的图片 - 然后我们可以自己查看。 @MarkSetchell 我已经发布了图片。由于它的大小只有 4x1 像素,因此几乎不可见,它位于 此处几乎不可见: 之后的问题中,并且看起来像一个省略号。图片链接为:i.stack.imgur.com/u5VW5.png

以上是关于如何获得具有 GD 的像素的正确 rgb 值?的主要内容,如果未能解决你的问题,请参考以下文章

Perl GD 检查像素是不是透明

如何通过鼠标单击获取像素的 rgb 颜色值

如果我知道颜色(RGB),如何获得像素坐标?

getPixel-method - 如何获得RGB的R值?

如何使用 PIL 确定具有共享值的像素区域

OpenCV:如何为每个像素填充具有每种 RGB 颜色值的 rgb 图像?