175 lines
3.9 KiB
Perl
175 lines
3.9 KiB
Perl
#!perl --
|
|
use strict;
|
|
use warnings;
|
|
use feature qw( say );
|
|
use File::Find;
|
|
use File::Path qw(make_path remove_tree);
|
|
use GD;
|
|
|
|
my $dry_run = grep{ $_ eq '--dry-run'} @ARGV;
|
|
|
|
my $resdir = 'app/src/main/res';
|
|
my $dstdir = 'tmp';
|
|
my $trimdir = 'trim24';
|
|
|
|
my $tmpfile = 'tmp/tmp.png';
|
|
|
|
my %density = (
|
|
mdpi => 1,
|
|
hdpi => 1.5,
|
|
xhdpi=> 2,
|
|
xxhdpi => 3,
|
|
xxxhdpi => 4,
|
|
);
|
|
|
|
sub savePng($$){
|
|
my($image,$path)=@_;
|
|
|
|
my $dir = $path;
|
|
$dir =~ s|/[^/]+\z||;
|
|
make_path($dir);
|
|
|
|
$image->saveAlpha(1);
|
|
open(my $fh,">",$path) or die "$path $!";
|
|
binmode $fh;
|
|
print $fh $image->png;
|
|
close($fh) or die "$path $!";
|
|
}
|
|
|
|
sub fix($){
|
|
my($relpath) = @_;
|
|
|
|
my $dstfile = "$dstdir/$relpath";
|
|
return if not $dstfile =~ s/(png|webp)\z/png/i;
|
|
my $ext = lc $1;
|
|
|
|
my $inData;
|
|
if( $ext eq "webp" ){
|
|
open(my $fh,"dwebp $relpath -quiet -o -|") or die "dwebp : $!";
|
|
binmode($fh);
|
|
local $/ = undef;
|
|
$inData = <$fh>;
|
|
close($fh) or die "dwebp: $!";
|
|
}else{
|
|
open(my $fh,"<",$relpath) or die "$relpath : $!";
|
|
binmode($fh);
|
|
local $/ = undef;
|
|
$inData = <$fh>;
|
|
close($fh) or die "$relpath : $!";
|
|
}
|
|
|
|
my $image = GD::Image->newFromPngData($inData,1);
|
|
|
|
my $width = $image->width;
|
|
my $height = $image->height;
|
|
my $alphaMax = 0;
|
|
my $isColor = 0 ;
|
|
Loop: for( my $y = 0; $y < $height ;++$y){
|
|
for( my $x = 0; $x < $width ;++$x){
|
|
my $c = $image->getPixel($x,$y);
|
|
my $c0 = ($c >> 24)&255; # GDのalphaは0が不透明、127が完全透明
|
|
my $r = ($c >> 16)&255;
|
|
my $g = ($c >> 8)&255;
|
|
my $b = ($c >> 0)&255;
|
|
if( abs($r-$g) >= 2 or abs($r-$b) >= 2 or abs($g-$b) >= 2 ){
|
|
$isColor = 1;
|
|
last Loop;
|
|
}
|
|
my $alpha= 127-$c0;
|
|
if( $alpha > $alphaMax){
|
|
$alphaMax = $alpha;
|
|
}
|
|
}
|
|
}
|
|
|
|
$relpath=~ /drawable-(\w+)/;
|
|
my $density = $density{ $1 };
|
|
|
|
if( $density and !$isColor){
|
|
my $dp_w = int(0.5 + $width/$density);
|
|
my $dp_h = int(0.5 + $height/$density);
|
|
if( $dp_w == 32 && $dp_h == 32 && 0 ){
|
|
say "${dp_w}x${dp_h}dp, alphaMax=$alphaMax, isColor=${isColor}, $relpath";
|
|
|
|
my $dstfile = "$trimdir/$relpath";
|
|
if( $dstfile =~ s/(png|webp)\z/png/i ){
|
|
if(0){
|
|
# create trimmed
|
|
my $trim_w = int(0.5 + $width * 24/32);
|
|
my $trim_h = int(0.5 + $height * 24/32);
|
|
my $offsetX = int($width-$trim_w)/2;
|
|
my $offsetY = int($width-$trim_w)/2;
|
|
|
|
my $i2 = GD::Image->newTrueColor($trim_w,$trim_h);
|
|
$i2->alphaBlending(0);
|
|
$i2->filledRectangle(0,0,$trim_w,$trim_h, $image->colorAllocateAlpha(0,0,0,127));
|
|
$i2->alphaBlending(1);
|
|
$i2->copy($image,0,0,$offsetX,$offsetY,$trim_w,$trim_h);
|
|
|
|
savePng($i2,$dstfile);
|
|
}else{
|
|
savePng($image,$dstfile);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return if $isColor;
|
|
return if $alphaMax == 0;
|
|
return if $alphaMax >= 126;
|
|
|
|
say "${width}x${height}, alphaMax=$alphaMax, isColor=${isColor}, $relpath";
|
|
|
|
my $scale = 127.0/$alphaMax;
|
|
|
|
for( my $y = 0; $y < $height ;++$y){
|
|
for( my $x = 0; $x < $width ;++$x){
|
|
my $c = $image->getPixel($x,$y);
|
|
my $c0 = ($c >> 24)&255; # GDのalphaは0が不透明、127が完全透明
|
|
my $r = ($c >> 16)&255;
|
|
my $g = ($c >> 8)&255;
|
|
my $b = ($c >> 0)&255;
|
|
next if $c0 == 127;
|
|
my $alpha= 127-$c0;
|
|
$c0 = 127 - int( 0.5 + $alpha * $scale );
|
|
my($rgb) = ($r+$g+$b >= 555 ? 0xffffff : 0x000000 );
|
|
$c = $rgb | ($c0 << 24 );
|
|
$image->setPixel($x,$y,$c);
|
|
}
|
|
}
|
|
|
|
savePng($image,$dstfile);
|
|
return if $dry_run;
|
|
|
|
if(1){
|
|
my $relpath_webp = $relpath;
|
|
$relpath_webp =~ s/(png|webp)\z/webp/i;
|
|
if( "png" eq lc $1 ){
|
|
unlink $relpath;
|
|
}
|
|
system qq(cwebp $dstfile -quiet -o $relpath_webp);
|
|
}
|
|
}
|
|
|
|
|
|
my @files;
|
|
find(
|
|
{
|
|
no_chdir => 1
|
|
,wanted =>sub{
|
|
my $relpath = $File::Find::name;
|
|
return if -d $relpath;
|
|
return if not $relpath =~ m|/drawable-|;
|
|
return if $relpath =~ m%/(media_type_|emoji_|media_bg_dark)%;
|
|
push @files,$relpath;
|
|
}
|
|
}
|
|
,$resdir
|
|
);
|
|
|
|
for my $relpath(@files){
|
|
fix($relpath);
|
|
}
|
|
|
|
|