⬆️ ⬇️

Re: Command line in the service of a Linux photographer

A recently published article “The command line in the service of a Linux photographer ”, in which the author writes about solving various typical tasks faced by a Linux photographer, but he obviously did not consider everything.



The first, or rather, zero task is to copy the images. It would seem that there is nothing in it that would be subject to optimization and automation: you can always press F5 in mc or drag files with the mouse or use some photo manager like digiKam. It is possible - but not necessary: ​​too many unnecessary movements. A Linux photographer (or rather, a Linux photographer who occasionally takes a photo) usually just needs to take the photos from the memory card, carefully fold them onto a hard disk, sorting them out, for example, by shooting time and, if they are annoying, remove them.



Another task that was discussed in the comments is batch reduction of photos and their signing. One of the methods is to use ImageMagick, to which various interfaces are available: as a command line interface (convert, mogrify, montage programs), and APIs for various programming languages. In the case of pearl - the module Image :: Magick . ImageMagick will allow both to reduce the photo and to sign it.

')

I automated similar tasks as follows:





Transfer photos:

#!/usr/bin/perl -wl use strict; use File::Find; use File::Path qw(make_path); use File::Copy; use Image::ExifTool qw(:Public); # You can change these variables my $PATH_SRC = '/media/NIKON/DCIM'; # path to memory card my $PATH_DST = $ENV{'HOME'} . '/photo'; # path to destination. Don't use ~ for your homedir my $PRECISION = 2; # 0 for year .. 5 for second my $MODE = 0644; # for chmod # Don't touch the rest of file find( \&wanted, $PATH_SRC ); sub wanted { return unless /\.jpg/i; my $new_name = lc $_; $new_name =~ s/^\D+//; my $info = ImageInfo( $File::Find::name ); my @date = split /\D+/, $info->{'DateTimeOriginal'}; $#date = $PRECISION; my $new_dir = join '/', $PATH_DST, @date; make_path $new_dir unless -d $new_dir; my $new_path = "$new_dir/$new_name"; -d $new_dir and move $File::Find::name, $new_path and chmod $MODE, $new_path and print "$File::Find::name => $new_path"; } # sub wanted 




Reducing and signing:

 #!/usr/bin/perl -w use strict; use Image::ExifTool ':Public'; use Image::Magick; use Getopt::Long; # Constants my %preferred_fonts = ( 'date' => [ qw/ DejaVuSans DejaVu-Sans Bitstream-Vera-Sans BitstreamVeraSans Verdana / ], # Normal width 'name' => [ qw/ DejaVuSansC DejaVu-Sans-Condensed Tahoma / ], # Narrow 'site' => [ qw/ DejaVuSansB BitstreamVeraSansB VerdanaB TahomaB / ], # Bold ); my $color = '#fff2'; my $gap = 10; my $name = (getpwuid $>)[6]; $name =~ s/,+$//; my $prefix = 'small.'; my $site = 'your-site.ru'; my $size = '50%'; # Override with options GetOptions( 'color:s' => \$color, 'gap:i' => \$gap, 'name:s' => \$name, 'prefix:s' => \$prefix, 'site:s' => \$site, 'size:s' => \$size, ); # Try to find suitable fonts my $image = new Image::Magick; my @available_fonts = $image->QueryFont(); my ( %seen, %fonts ); map { $seen{$_} = 1 } @available_fonts; while ( my ( $scope, $list ) = each %preferred_fonts ) { foreach ( @$list ) { $fonts{ $scope } = $_ and last if $seen{$_}; } # foreach } # while foreach my $file ( @ARGV ) { my $info = ImageInfo($file, 'CreateDate'); my $date = $$info{'CreateDate'}; my $new_file_name = $file; $new_file_name =~ s{([^/]+)$}{$prefix$1}; $date =~ s/^(\d{4}):(\d{2}):(\d{2}).*/$3.$2.$1/; my $p = new Image::Magick or next; $p->Read( $file ); $p->AutoOrient; $p->Resize( 'geometry' => $size, 'filter' => 'Lanczos', 'blur' => 0.5, ); my ( $width, $height ) = $p->Get('width', 'height'); my ( $x, $y ) = ( $width - $gap, $height - $gap ); $p->Set( 'pointsize' => 12, 'fill' => $color, ); $p->Annotate( 'font' => $fonts{'name'}, 'text' => $name, 'rotate' => -90, 'x' => $x, 'y' => $y, ); $y -= ( $p->QueryFontMetrics( 'font' => $fonts{'name'}, 'text' => $name, ) )[4] + $gap; $p->Annotate( 'font' => $fonts{'site'}, 'text' => $site, 'rotate' => -90, 'x' => $x, 'y' => $y, ); $y -= ( $p->QueryFontMetrics( 'font' => $fonts{'site'}, 'text' => $site, ) )[4] + $gap; $p->Annotate( 'font' => $fonts{'date'}, 'text' => $date, 'rotate' => -90, 'x' => $x, 'y' => $y, ); $p->Sharpen( 'radius' => 1, 'sigma' => 2, ); $p->Write($new_file_name); print "$file - $date\n"; } # foreach 




Ready scripts and documentation for them are posted on github.com:

Source: https://habr.com/ru/post/128527/



All Articles