[Perl][图片处理]判断一张壁纸是深色还是浅色
发表于 : 2022年12月12日 21:20
参考:
StackOverflow - How can i easily extract the percentage of colors of an image?
使用 ImageMagick 图片对象的 Histogram 方法,获取一张图片的所有RGB颜色值和频率数据。
提取到二维数组,排序,按频率最高的颜色的深度做判断Android 判断颜色为深颜色还是浅颜色来动态调整app文字和图标颜色
单纯通过 R G B 求和作为深色或是浅色的依据,有时候不太符合直觉(肉眼直观感受不同),
转换成 YUV模式,采用其中的亮度Y(灰阶)作为参考。代码: 全选
$Y = $R * 0.299 + $G * 0.587 + $B * 0.114
StackOverflow - Detect if background wallpaper is too light or too dark
取所有颜色的平均值,作为深色、浅色的判断依据
结合以上参考,写出最终代码:
代码: 全选
use utf8;
use Encode;
use Modern::Perl;
use File::Slurp;
use Image::Magick;
use JSON qw/from_json to_json/;
STDOUT->autoflush(1);
# 图片路径使用 gbk编码,关键字使用 Unicode
my $pics = [
gbk("../壁纸/壁纸1.png"),
gbk("../壁纸/壁纸2.png")
];
for my $e ( @$pics )
{
my ($r, $g, $b) = get_avg_color( $e );
say $e;
# 转换成YUV格式的亮度值
my $value = sprintf "%.2f", $r * 0.299 + $g * 0.587 + $b * 0.114;
say $value;
}
write_file($cfg_file, gbk($cfg));
# 获取所有像素颜色的平均值
sub get_avg_color
{
my ( $pic ) = @_;
my $img = Image::Magick->new();
$img->Read( decode('gbk', $pic) );
my @hist_data = $img->Histogram;
my @hist_entries;
# Histogram returns data as a single list, but the list is actually groups of
# 5 elements. Turn it into a list of useful hashes.
my $sum = {'r' => 0, 'g' => 0, 'b' => 0};
my $pixels = 0;
while ( @hist_data )
{
my ($r, $g, $b, $a, $count) = splice @hist_data, 0, 5;
$sum->{'r'} += ($r / 255) * $count;
$sum->{'g'} += ($g / 255) * $count;
$sum->{'b'} += ($b / 255) * $count;
$pixels += $count;
}
$sum->{'r'} /= $pixels;
$sum->{'g'} /= $pixels;
$sum->{'b'} /= $pixels;
return @{$sum}{'r','g','b'};
}
sub gbk { encode('gbk', $_[0]) }
sub utf8 { encode('utf8', $_[0]) }
sub u2gbk { encode('gbk', decode('utf8', $_[0])) }
sub uni { decode('utf8', $_[0]) }