Created
July 29, 2020 12:02
-
-
Save Zrubi/60ec60eb857cf754311fbd7a2d5fcad6 to your computer and use it in GitHub Desktop.
My very basic Photo pre-processing script
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
work_dir = /home/user/tmp/import | |
<model> | |
<default> | |
prefix = OOO_00 | |
author = Z | |
</default> | |
<D70> | |
orig = "dsc_\d{4}\.jpg" | |
author = Zrubi | |
prefix = D70_04 | |
convert = -quality 95 | |
# convert = -quality 95 -scale 1000x1000 | |
</D70> | |
<D7100> | |
orig = "dsc_\d{4}\.jpg" | |
author = Zrubi | |
prefix = D7100_01 | |
# convert = -quality 95 | |
convert = -quality 95 -scale 1920x1920 | |
</D7100> | |
<D40> | |
orig = "dsc_\d{4}\.jpg" | |
author = Zr | |
prefix = D40_00 | |
convert = -quality 95 | |
</D40> | |
</model> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/perl -w | |
use strict; | |
use Getopt::Long; | |
Getopt::Long::Configure ("bundling", "no_auto_abbrev"); | |
use Config::General qw(ParseConfig); | |
use File::Basename; | |
use File::Copy; | |
use File::Find; | |
use File::Path; | |
#use File::stat; | |
#use Digest::MD5; | |
use Image::ExifTool; | |
use POSIX qw(strftime); | |
use Date::Parse; | |
#use Pod::Usage; | |
use Data::Dumper; | |
# kapcsolok | |
my ($help, $man, $ver); | |
my ($purge, $author, $prefix, $date, $dateshift, $rename, $convert, $assign, $stat); | |
my $loglevel = 1; | |
my $debug_level = 5; | |
my $target=0; | |
# konfig | |
my %conf; | |
my $temp_dir; | |
my %originals; | |
my %reworks; | |
my %skipped; | |
my %new_models; | |
srand; | |
sub myprint | |
{ | |
my $string = shift; | |
my $level = shift; | |
if ($loglevel >= $level) | |
{ | |
#print STDOUT strftime("%Y-%m-%d %T",localtime()), " $string\n"; | |
print STDOUT "$string\n"; | |
} | |
} | |
sub process_file { | |
assign($_); | |
print "$_\n"; | |
} | |
sub get_originals { | |
my $file = $_; | |
my $know_model; | |
my $original; | |
my %f = () ; | |
if (-f $file) { | |
my $exifTool = new Image::ExifTool; | |
my $info = $exifTool->ImageInfo($file); | |
myprint(Data::Dumper->Dump([\$info], ['*exifdata']), $debug_level); | |
#$f{$file}{'file'} = $file; | |
$f{$file}{'path'} = $File::Find::name; | |
#$f{$file}{'name'} = fileparse($File::Find::name, qr/.(jpg)/i);; | |
my ($name,$path,$suffix) = fileparse($File::Find::name, qr/.(jpg|jpeg)/i); | |
$f{$file}{'name'} = $name; | |
if (!$suffix) { | |
$skipped{$file} = $f{$file}; | |
return 1; | |
} | |
# van-e ilyen exif mezo egyatalan? | |
if ( $exifTool->GetValue('Model') ){ | |
$f{$file}{'model'} = $exifTool->GetValue('Model'); | |
while ( my($model, $value) = each %{$conf{'model'}}) { | |
# matchel-e a configban felvettek kozul valamelyikkel | |
#print "MATCH? '" .$exifTool->GetValue('Model') ."' =~ '$model'\n"; | |
if ($exifTool->GetValue('Model') =~ $model){ | |
$know_model = $model; | |
#print "MATCHED!: '$model'\n"; | |
# illeszkedik-e a file neve a model alatt megadott mintara | |
if ($conf{'model'}{$model}{'orig'} and lc($file) =~ $conf{'model'}{$model}{'orig'}){ | |
#print "MATCH: '$file' =~ '$conf{'model'}{$model}{'orig'}'\n"; | |
$original = 1; | |
} | |
} | |
elsif(!$know_model){ | |
# tehat van 'Model' exif tag, de nincs felveve a konfigba: | |
# ezeket eredetinek kezeljuk | |
$original = 1; | |
} | |
} | |
# globalisan megadott author eseten: | |
if ($author){ | |
$f{$file}{'author'} = $author; | |
} | |
# model szekcioban megadott author eseten: | |
elsif($know_model){ | |
$f{$file}{'author'} = $conf{'model'}{$know_model}{'author'}; | |
} | |
# default szekcioban megadott author eseten: | |
elsif ($conf{'model'}{'default'}{'author'}){ | |
$f{$file}{'author'} = $conf{'model'}{'default'}{'author'}; | |
} | |
# globalisan megadott prefix eseten: | |
if ($prefix){ | |
$f{$file}{'prefix'} = $prefix; | |
} | |
# model szekcioban megadott prefix eseten: | |
elsif($know_model){ | |
$f{$file}{'prefix'} = $conf{'model'}{$know_model}{'prefix'}; | |
} | |
# default szekcioban megadott prefix eseten: | |
elsif ($conf{'model'}{'default'}{'prefix'}){ | |
$f{$file}{'prefix'} = $conf{'model'}{'default'}{'prefix'}; | |
} | |
# globalisan megadott convert eseten: | |
if ($convert){ | |
$f{$file}{'convert'} = $convert; | |
} | |
# model szekcioban megadott convert eseten: | |
elsif($know_model){ | |
$f{$file}{'convert'} = $conf{'model'}{$know_model}{'convert'}; | |
} | |
# default szekcioban megadott convert eseten: | |
elsif ($conf{'model'}{'default'}{'convert'}){ | |
$f{$file}{'convert'} = $conf{'model'}{'default'}{'convert'}; | |
} | |
$f{$file}{'date'} = $exifTool->GetValue('DateTimeOriginal') if $exifTool->GetValue('DateTimeOriginal'); | |
# begyujtjuk az eredetinek minositett kepeket: | |
$originals{$file} = $f{$file} if $original; | |
# es gyujtjuk az ismeretlen model-re vonatkozo exif adatokat is: | |
$new_models{$exifTool->GetValue('Model')} = $exifTool->GetValue('Make') if !$know_model; | |
} | |
if (!$original){ | |
#$f{$file}{'modif'} = "BW" if $exifTool->GetValue('ColorComponents') == 1; | |
$reworks{$file} = $f{$file}; | |
} | |
} | |
} | |
sub assign_files{ | |
my $action = shift; | |
my ($orig_filename, $rev_filename, $d, $serial, $rev, $ext); | |
myprint(Data::Dumper->Dump([\%originals], ['*originals']), 4) if $action eq "print"; | |
myprint(Data::Dumper->Dump([\%reworks], ['*Reworks']), 4) if $action eq "print"; | |
foreach my $orig_key (sort keys %originals){ | |
my $f = $orig_key; | |
my $i = $f =~ /(\d{4,6})/; | |
$serial = $1; | |
$rev = 0; | |
$d = strftime("%Y%m%d", localtime(str2time($originals{$orig_key}{'date'}))); | |
$ext = ".jpg"; | |
#$orig_filename = $d ."-" .$originals{$orig_key}{'prefix'} .$serial ."-r" .sprintf("%02d",$rev) .$ext; | |
$orig_filename = $d ."-" .$originals{$orig_key}{'prefix'} .$serial .$ext; | |
print "\t$orig_key\t$originals{$orig_key}{'date'}\t$originals{$orig_key}{'model'} \n" if $action eq "print"; | |
if ($action eq "rename"){ | |
myprint("\tRenaming file: '$orig_key' -> $orig_filename",3); | |
rename("$temp_dir/$orig_key","$temp_dir/$orig_filename"); | |
} | |
foreach my $rev_key (keys %reworks){ | |
if ($reworks{$rev_key}{'name'} =~ $serial){ | |
#if ($reworks{$rev_key}{'name'} =~ $originals{$orig_key}{'name'}){ | |
$rev++; | |
if ($action eq "print"){ | |
print "\t\t-> $rev_key\n"; | |
} | |
elsif ($action eq "rename"){ | |
#$rev_filename = $d ."-" .$originals{$orig_key}{'prefix'} .$serial ."-r" .sprintf("%02d",$rev) .$ext; | |
$rev_filename = $d ."-" .$originals{$orig_key}{'prefix'} .$serial ."-$rev" .$ext; | |
myprint("\tRenaming file: '$rev_key' -> $rev_filename",3); | |
rename("$temp_dir/$rev_key","$temp_dir/$rev_filename"); | |
system("exiftool -q -overwrite_original -TagsFromFile $temp_dir/$orig_filename -exif:all $temp_dir/$rev_filename") | |
and "File: '$temp_dir/$rev_filename' cannot be modify: $!"; | |
} | |
else{ | |
system("exiftool -q -overwrite_original -TagsFromFile $originals{$orig_key}{path} -exif:all $reworks{$rev_key}{path}") | |
and "File: '$reworks{$rev_key}{path}' cannot be modify: $!"; | |
} | |
} | |
} | |
print "\n" if $action eq "print"; | |
} | |
print "\n"; | |
} | |
sub print_stat{ | |
assign_files('print'); | |
} | |
sub copy_files{ | |
foreach (keys %reworks){ | |
myprint ("copy $reworks{$_}{'path'} $temp_dir/$_",$debug_level); | |
copy("$reworks{$_}{'path'}", "$temp_dir/$_") or die "File: '$reworks{$_}{'path'}' cannot be copied: $!"; | |
} | |
foreach (keys %originals){ | |
if ($originals{$_}{'convert'}){ | |
myprint ("convert $originals{$_}{'path'} $originals{$_}{'convert'} $temp_dir/$_",$debug_level); | |
system("convert $originals{$_}{'path'} $originals{$_}{'convert'} $temp_dir/$_") and die "File: '$originals{$_}{'path'}' cannot be convert: $!"; | |
} | |
else{ | |
myprint ("copy $originals{$_}{'path'} $temp_dir/$_",$debug_level); | |
copy("$originals{$_}{'path'}", "$temp_dir/$_") or die "File: '$reworks{$_}{'path'}' cannot be copied: $!"; | |
} | |
} | |
} | |
sub exif_rewrite { | |
my $file; | |
foreach (keys %originals){ | |
$file = $originals{$_}{'path'}; | |
if (-f $file) { | |
my $exifTool = new Image::ExifTool; | |
my $info = $exifTool->ImageInfo($file); | |
if ($originals{$_}{'author'}){ | |
$exifTool->SetNewValue(Author => $originals{$_}{'author'}); | |
} | |
if ($purge){ | |
$exifTool->SetNewValue(PreviewImage => ''); | |
$exifTool->SetNewValue('ThumbnailImage'); | |
} | |
my $w_result = $exifTool->WriteInfo($file); | |
myprint ("WriteInfo: $w_result\n", $debug_level) if $w_result; | |
print "ERROR:" .$exifTool->GetValue('Error') ."\n" if $exifTool->GetValue('Error'); | |
print "Warning:" .$exifTool->GetValue('Warning') ."\n" if $exifTool->GetValue('Warning'); | |
} | |
} | |
} | |
GetOptions ('help' => \$help, 'man' => \$man, 'version|V' => \$ver, | |
'loglevel=i' => \$loglevel, | |
'author=s' => \$author, | |
'prefix=s' => \$prefix, | |
'date=s' => \$date, | |
'dateshift=s' => \$dateshift, | |
'purge' => \$purge, | |
'rename' => \$rename, | |
'convert' => \$convert, | |
'assign' => \$assign, | |
'stat' => \$stat, | |
) || pod2usage(1); | |
pod2usage(1) if $help; | |
pod2usage(-verbose => 2) if $man; | |
print_version() if $ver; | |
# konfig beolvasasa: | |
%conf = ParseConfig( | |
-ConfigFile => ".preprocess.conf", | |
-ConfigPath => "$ENV{HOME}/"); | |
myprint(Data::Dumper->Dump([\%conf], ['*conf']), $debug_level); | |
if (!$stat){ | |
$temp_dir = "$conf{work_dir}/" .time(); | |
myprint("Creating temporary directory: '$temp_dir'", 3); | |
mkpath("$temp_dir", 0, 0750) or die("Couldn't make temporary directory: '$temp_dir': $!"); | |
} | |
foreach $target (@ARGV){ | |
$target =~ s/\/*$//; | |
myprint("Processing directory: '$target'", 1); | |
find(\&get_originals, $target); | |
myprint(Data::Dumper->Dump([\%originals], ['*originals']), 4); | |
myprint(Data::Dumper->Dump([\%reworks], ['*reworks']), 4); | |
myprint(Data::Dumper->Dump([\%skipped], ['*skipped']), 2); | |
myprint(Data::Dumper->Dump([\%new_models], ['*new_models']), 2); | |
if ($stat){ | |
print_stat(); | |
} | |
else{ | |
myprint("Copying files from directory: '$target'", 1); | |
copy_files(); | |
%originals = (); | |
%reworks = (); | |
find(\&get_originals, $temp_dir); | |
myprint(Data::Dumper->Dump([\%originals], ['*Originals']), 5); | |
myprint(Data::Dumper->Dump([\%reworks], ['*Reworks']), 5); | |
myprint(Data::Dumper->Dump([\%skipped], ['*Skipped']), 5); | |
myprint("Modifying EXIF data in files", 2); | |
exif_rewrite(); | |
if ($assign){ | |
if ($rename){ | |
assign_files('rename'); | |
} | |
else{ | |
assign_files('rewrite'); | |
} | |
} | |
myprint("You can find the processed files in: $temp_dir",1); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment