#!/usr/bin/env perl use strict; use warnings; use Data::Dumper; use Image::Magick; use constant {DEBUG => 0}; our $VERSION = '1.00'; my @digitchar = (0..9, ':', ' '); my @digittime = ( [744, 372, 372, 744], # 0 [186, 1116], # 1 [558, 558, 558, 558], # 2 [372, 372, 558, 558], # 3 [372, 372, 1116, 186], # 4 [558, 558, 558, -558], # 5 [744, 558, 558, 558], # 6 [255, 640, 1025, 895, 539], ## 7 [1020, 648, 510, 648, 1020], ## 8 [558, 558, 558, 744], # 9 [372], ## / [], # - ); my @digitgreen = ( [1344, 393, 255, 393, 1344], # 0 [255, 409, 1530], # 1 [863, 709, 664, 799, 648], # 2 [579, 393, 510, 648, 1089], # 3 [640, 709, 709, 1530, 255], # 4 [523, 895, 510, 770, 1150], # 5 [1344, 786, 648, 648, 1089], # 6 [255, 640, 1025, 895, 539], # 7 [1020, 648, 510, 648, 1020], # 8 [903, 648, 510, 648, 1344], # 9 [199, 887, 709], ## / # [1344, 417, 263, 393, 1344, 32], # 0 # [255, 417, 1530, 40], # 1 # [863, 725, 680, 807, 656, 16], # 2 # [579, 401, 518, 656, 1089, 24], # 3 # [640, 717, 725, 1530, 287, 8], # 4 # [523, 903, 526, 778, 1158, 24], ## 5 # [1344, 786, 656, 656, 1097, 24], ## 6 # [255, 648, 1033, 911, 547, 8], # 7 # [1028, 656, 526, 664, 1028, 24], # 8 # [903, 656, 526, 656, 1344, 32], # 9 # [199, 887, 725, 16], ## / [], # - ); my %colorgreen = ( # 8 => [8, 8], 69 => [0, 0], 130 => [8, 8], 154 => [33, 33], 255 => [16, 24], ); sub getrect2 { my ($digit, $valid, $data, $w, $h, $x1, $x2) = @_; my ($str, @char); my $count = -1; for my $x ($x1 .. $x2) { my $colval = 0; for my $y (0 .. $h - 1) { my @val; push @val => $data->[($x + $y*$w) * 3 + $_] >> 8 for 0 .. 2; printf(" [%s]\n", join ', ', @val) if DEBUG >= 2; my $match = $valid->{$val[1]} or next; $val[0] == $match->[0] and $val[2] == $match->[1] or next; print " ok\n" if DEBUG >= 2; $colval += $val[1]; } if ($colval > 0 and ($count < 0 or $count++ < 6)) { push @char => $colval; } elsif (@char) { printf " %d: [%s], # %d\n", $x, join(', ', @char), $count if DEBUG >= 1; my @matches; for my $match (@$digit) { if (scalar @$match == scalar @char) { my $offset = 0; $offset += abs $char[$_] - $match->[$_] for 0 .. $#char; push @matches => $offset; } else { push @matches => -1; } } undef @char; $count = 0; my $best; $matches[$_] == 0 and $best = $_ for 0 .. $#matches; if (not defined $best) { my @best; $matches[$_] > 0 and push @best, $_ for sort {$matches[$a] <=> $matches[$b]} 0 .. $#matches; printf "candidates: (%s)\n", join ', ', map {"$_ ($matches[$_])"} @best; $best = shift @best; } $str .= defined $best ? $best eq '' ? '' : $digitchar[$best] : '?'; } } return $str; } my $map = Image::Magick->new(128, 128); my $curtime = 0; for my $i ($ARGV[0] .. $ARGV[1]) { my $image = Image::Magick->new; my $err = $image->Read(sprintf 's%05d.png', $i); $err and die $err; my @pixels = $image->GetPixels(map=>'RGB', x=>452, width=>187, y=>6, height=>6); my $min = getrect2(\@digitgreen, \%colorgreen, \@pixels, 187, 6, 0, 39); my $gas = getrect2(\@digitgreen, \%colorgreen, \@pixels, 187, 6, 68, 107); my $unit = getrect2(\@digitgreen, \%colorgreen, \@pixels, 187, 6, 136, 181); my ($unitcur, $unitmax) = split /:/, $unit, 2; @pixels = $image->GetPixels(map=>'RGB', x=>587, width=>34, y=>396, height=>6); my $time = getrect2(\@digittime, {186 => [189, 239]}, \@pixels, 34, 6, 0, 33); my $sec; $time =~ /^(\d\d):(\d\d)$/ and $sec = $1*60 + $2; printf "%d:\t%s\t%s\t%s\t%s\t%s\n", $i, $sec, $min, $gas, $unitcur, $unitmax; $image->Crop(width=>128, height=>128, x=>6, y=>348); # $image->Set(delay => $sec > $curtime ? ($sec - $curtime) / 5 : 10); $image->Set(10); push @$map => $image; $curtime = $sec; } my $err = $map->Write('map.gif'); $err and die $err; #print $map->Layers(method => 'optimize'); print "\n"; print "\n";