使用Perl修改图像中的像素

时间:2012-03-08 19:23:08

标签: perl

假设我想拍摄一张照片,将其所有像素向右移动一个像素,向左移动一个像素,然后保存。我试过这段代码:

my $image_file = "a.jpg";
my $im = GD::Image->newFromJpeg($image_file);
my ($width, $height) = $im->getBounds();
my $outim = new GD::Image($width, $height);

foreach my $x (1..$width)
{
    foreach my $y (1..$height)
    {
        my $index = $im->getPixel($x-1,$y-1);
        my ($r,$g,$b) = $im->rgb($index);
        my $color = $outim->colorAllocate($r,$g,$b);
        $outim->setPixel($x,$y,$color);
    }
}
%printing the picture...

这不是诀窍;它以一种颜色绘制除x = 0或y = 0之外的所有像素。我哪里错了?

4 个答案:

答案 0 :(得分:4)

查看文档:

  

通过阅读JPEG图像创建的图像将始终为truecolor。至   强制图像为基于调色板,在可选项中传递值0   $ truecolor参数。

它没有编入索引。尝试在,0来电中添加newFromJpeg

从评论中看,您的下一个问题似乎是要分配的颜色数量。默认情况下,索引图像为8位,表示最多256个唯一颜色(2 ^ 8 = 256)。 “简单”的解决方法当然是使用真彩色图像,但这取决于您是否可以接受真彩色输出。

如果没有,您的下一个挑战将是提出256种颜色的“最佳”设置,以尽量减少图像本身的可见缺陷(参见http://en.wikipedia.org/wiki/Color_quantization)。这本身就是一个完整的话题,我们今天很少担心。如果您仍然需要担心它,您可能最好将该工作卸载到像Imagemagik或类似的专业工具,而不是尝试自己实现它。除非你当然喜欢挑战。

答案 1 :(得分:2)

这是使用Imager的解决方案,因为它是一个非常好的模块,我对它更熟悉,并且它很好地处理图像变换。

use Imager;

my $image_file = "a.jpg";

my $src = Imager->new(file => $image_file) or die Imager->errstr;

my $dest = Imager->new(
    xsize => $src->getwidth() + 1,
    ysize => $src->getheight() + 1,
    channels => $src->getchannels
);

$dest->paste(left => 1, top => 1, src => $src);
$dest->write(file => "b.jpg") or die $dest->errstr;

答案 2 :(得分:0)

尝试反转x和y的方向 - 不是从1到最大,而是从最大到1。你不是滑动颜色,而是一次又一次地复制颜色。

答案 3 :(得分:0)

我意识到这是一篇旧帖子,但这是我使用 GD:Thumb 创建调整大小图像的一段代码。

    sub png {
        my ($orig,$n) = (shift,shift);
        my ($ox,$oy) = $orig->getBounds();
        my $r = $ox>$oy ? $ox / $n : $oy / $n;
        my $thumb = GD::Image->newFromPng($ox/$r,$oy/$r,[0]);
        $thumb->copyResized($orig,0,0,0,0,$ox/$r,$oy/$r,$ox,$oy);
        return $thumb, sprintf("%.0f",$ox/$r), sprintf("%.0f",$oy/$r);
        }