使用 ImageMagick/perl 自定义颜色反转算法
我有一些现有的 C# 代码,我正在尝试将其迁移到开源脚本语言。总体思路是读取 PNG 图像,并对其执行“自定义反转”颜色转换。
我想要:
- 简单地反转所有灰度(即 R=G=B)像素(使用
convert +negate
非常适合此操作!) - 仅否定所有的亮度非灰度像素(即亮度 1 变为 0,.2 变为 .8)
迭代像素并使用 Graphics::ColorObject 将 RGB 转换为 HSL 可能是一种解决方案,但脚本我写的这样做速度非常慢,而在我的 C# 代码中(如果我能够在 .NET 环境中运行它,我会使用它),转换图像只需要一两秒。
我猜想这可以通过一个或多个连续的 convert
命令实现(因为 convert +negate
轻松完成#1),但我不确定如何执行#2。
这是我的 Perl 代码,速度非常慢,实际上我无法确定它是否有效,因为它需要很长时间。我不是一个 Perl 程序员,所以我确信这可以优化多次。
#!/usr/local/bin/perl
use Image::Magick;
use Graphics::ColorObject;
my $image;
$image = new Image::Magick;
$image->Read($ARGV[0]);
my $width = $image->Get('width');
my $height = $image->Get('height');
my $w = 0;
my $h = 0;
for($w=0; $w GetPixel(x=>$w,y=>$h);
#print "checking $w $h: $r $g $b\n";
if($r == $g && $g == $b) {
# grey scale - invert
$r = 1 - $r;
$g = 1 - $g;
$b = 1 - $b;
} else {
# convert only luminance
$color = Graphics::ColorObject->new_RGB([$r, $g, $b]);
($h, $s, $l) = @{ $color->as_HSL() };
$l = 1 - $l;
$newcolor = Graphics::ColorObject->new_HSL([$h, $s, $l]);
($r, $g, $b) = @{ $newcolor->as_RGB() };
}
$image->SetPixel(x=>$w,y=>$h,color=>[$r, $g, $b]);
}
}
$image->Write($ARGV[0] + "_i");
I have some existing code in C# that I'm trying to move to an open source scripting language. The general idea is to read in a PNG image, and perform a "custom inversion" color transformation on it.
I want to:
- simply invert all greyscale (ie R=G=B) pixels (using
convert +negate
works great for this!) - negate the luminance, only, of all non-greyscale pixels (ie, luminance of 1 becomes 0, .2 becomes .8)
Iterating through the pixels and using Graphics::ColorObject
to convert the RGB to HSL may be a solution, but the script I wrote to do that is extremely slow, whereas in my C# code (which I would use if I was able to run this in a .NET environment) it only takes a second or two to convert an image.
I'm guessing this is possible with one or more successive convert
commands (since convert +negate
accomplishes #1 easily) but am not sure how to do #2.
This is my extremely slow perl code, that I actually haven't been able to determine if it works because it takes so long. I am NOT much of a perl programmer, so I'm sure this can be optimized several times over.
#!/usr/local/bin/perl
use Image::Magick;
use Graphics::ColorObject;
my $image;
$image = new Image::Magick;
$image->Read($ARGV[0]);
my $width = $image->Get('width');
my $height = $image->Get('height');
my $w = 0;
my $h = 0;
for($w=0; $w GetPixel(x=>$w,y=>$h);
#print "checking $w $h: $r $g $b\n";
if($r == $g && $g == $b) {
# grey scale - invert
$r = 1 - $r;
$g = 1 - $g;
$b = 1 - $b;
} else {
# convert only luminance
$color = Graphics::ColorObject->new_RGB([$r, $g, $b]);
($h, $s, $l) = @{ $color->as_HSL() };
$l = 1 - $l;
$newcolor = Graphics::ColorObject->new_HSL([$h, $s, $l]);
($r, $g, $b) = @{ $newcolor->as_RGB() };
}
$image->SetPixel(x=>$w,y=>$h,color=>[$r, $g, $b]);
}
}
$image->Write($ARGV[0] + "_i");
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我希望这就是您使用 convert 寻找的结果(在 Ubuntu 上使用 ImageMagick 完成)
结果是(原始左侧)
I expect this is what you are looking for using convert (done with ImageMagick on Ubuntu)
Result is (original left)