DesktopAlbum

use strict;
use warnings;

use Digest;
use File::Temp qw/:seekable/;
use Image::Info qw/image_info dim/;
use Imager;

my $width  = 1400;
my $height = 1050;

opendir my $d, '.' or die $!;

while (defined($_ = readdir $d)) {
    next unless /(?:jpe?g|png|bmp)$/i;
    
    my $info = image_info $_;
    die "Can't parse: ", $info->{error}, "\n" if $info->{error};
    my ($w, $h) = dim $info;
    next if sprintf("%.3f", $h/$w) != $height/$width;
    
    print "$_\n";
    
    my $img = Imager->new or die "Imager->new err\n";
    $img->read(file => $_) or die $img->errstr;
    
    $img = $img->convert(preset => 'noalpha') or die $img->errstr;
    unless ($w == $width and $h == $height) {
        $img = $img->scale(xpixels => $width, ypixels => $height, type => 'nonprop') or die $img->errstr;
        $img->filter(type => 'unsharpmask', stddev => 0.5, scale => 0.25);
    }
    
    my $tmp = File::Temp->new(SUFFIX => '.png') or die $!;
    $img->write(fh => $tmp, type => 'png') or die $img->errstr;
    $tmp->seek(0, SEEK_SET);
    
    my @t = localtime;
    my $date = sprintf '%4d%02d%02d%02d%02d%02d',
        $t[5] + 1900, $t[4] + 1, $t[3],
        $t[2], $t[1], $t[0];
    
    my $sha = Digest->new('SHA-256') or die "Digest->new err\n";
    open my $src, '<:raw', $_ or die $!;
    $sha->addfile($src);
    my $fp = substr $sha->hexdigest, 0, 8;
    close $src;
    
    open my $fh, '>:raw', "$date.ALB" or die $!;
    print $fh pack a20a8LLLa16a72x8N => 'DesktopAlbum101', 'PNG', $width, $height, 32, $date, "fp(sha256: $fp)", -s $tmp;
    while (read $tmp, my $buf, 262144) {
        print $fh $buf;
    }
    close $fh;
    
    unlink $_;
}

closedir $d;

DesktopAlbum用に変換するだけのスクリプト。あんまり変なことはしてないから、コード読めば何してるか大体わかるでしょ。packでいろいろ埋めてるヘッダ部分は、以前に作者さんに直接メールして確認したからフォーマットはこれであってるはず。誰も使わないだろうけど、せっかく書いておいて放置するのもアレだし、ちょろっと載せておこうかなーと。