假设我想拍摄一张照片,将其所有像素向右移动一个像素,向左移动一个像素,然后保存。我试过这段代码:
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之外的所有像素。我哪里错了?
答案 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);
}