Spegla mappträd med bilder och förminska bilderna?

Permalänk

Spegla mappträd med bilder och förminska bilderna?

Hej

Finns det något smidigt sätt att kopiera en mappstruktur med den extra krusidullen att jag vill förminska bilderna? Helst skulle det vara ett script som endast kopierar/förminskar de nya bilder sen förra gången. Tidigare har jag använt ImageMagick men då har jag manuellt öppnat varje mapp och startat förminskningen.

Permalänk
Medlem

Jag har inget vettigt för mig idag så jag kan tänka mig titta på det. Jag har redan ett perlskript som förenklar förminskning av bilder med hjälp av ImageMagick som troligen kan byggas ut för dina behov. Jag ska iväg på annat nu men jag återkommer nog senare idag om jag har lyckats med något

Permalänk
Medlem
Skrivet av Kuufukuji:

Jag har inget vettigt för mig idag så jag kan tänka mig titta på det. Jag har redan ett perlskript som förenklar förminskning av bilder med hjälp av ImageMagick som troligen kan byggas ut för dina behov. Jag ska iväg på annat nu men jag återkommer nog senare idag om jag har lyckats med något

please do!

Permalänk
Medlem

Skrev ihop ett skript lite snabbt. Dessvärre är det lite av ett fulhack då det först kopierar mappstrukturen inklusive alla bilder och sedan i efterhand förminskar bilderna.

Koden finns nedan eller på denna direktlänk.

#!/usr/bin/perl use warnings; use strict; use Getopt::Std; # Variabel med standardvärde ifall mappstrukturen ska kopieras eller ej # 1 = ska kopiera den # 0 = ska EJ kopiera den # Denna variabler ändras ifall -c skickas in. my $copy = 0; # Usagesträng my $usage = "Usage: resimg [-c] dir size [new_dir] Where dir: is an existing directory; size: is an integer for the new image size; [new_dir]: is a new directory name (default 'dir'_'size'px); Example: resimg Pictures/ 800 Picturs_in_800\n\n"; if ($copy) { $usage = $usage . "Copying is ON by default (\$copy = 1)\n"; } else { $usage = $usage . "Copying is OFF by default (\$copy = 0)\n"; } $usage = $usage . "\tChange by using option '-c'\n"; # Flagga -c för att switcha $copy. Det innebär att ifal $copy är satt som 1 så kommer # -c innebära att $copy blir 0, och tvärtom. our ($opt_c); getopt(@ARGV); if ($opt_c) { $copy = 1 - $copy; } # Andra variabler... my $dir; my $size; my $new_dir; my @images; # Kollar om argumentet $size är en integer if ($ARGV[1] && $ARGV[1] !~ /^-?\d+$/) { die("Size argument is not an integer.\n\n$usage"); } # Granskar argumenten och tilldelar variabler if ($ARGV[0] && $ARGV[1]) { $dir = $ARGV[0]; $size = $ARGV[1]; $dir =~ s/\/$//; } else { die($usage); } # Tilldelar nya mappens namn om mappstrukturen ska kopieras ($copy = 1) if ($copy) { if ($ARGV[2]) { $new_dir = $ARGV[2]; } else { $new_dir = $dir . "_" . $size . "px"; } # Kopierar mappstrukturen till den nya mappen my $cmd; $cmd = "cp -r " . $dir . " " . $new_dir; print("Copying all files (" . $cmd . ").\n"); system($cmd); } # Letar reda på alla bildfiler if ($copy) { @images = look_dir($new_dir); } else { @images = look_dir($dir); } # Lite output print(($#images+1) . " images was found.\n"); # Konvertering av bildfiler my $i = 1; foreach my $img (@images) { $img =~ s/ /\ /g; system("convert -thumbnail " . $size . "x" . $size . " '" . $img . "' '" .$img."'"); print("\t$i/".($#images+1)."\t$img\n"); $i++; } # Avslut print(($#images+1) . " images was converted.\n"); ################################################################################ # look_dir(@DIRECTORY) => @FILELIST # # Subrutin för att rekursivt leta efter alla bilder och förminska dem ################################################################################ sub look_dir { my @all_dir = @_; my @list; foreach my $cur_dir (@all_dir) { opendir(FOLDER, "$cur_dir") or die("ERROR: Couldn't open directory '$cur_dir'\n"); my @dir = readdir(FOLDER); closedir(FOLDER); for (@dir) { next if($_ eq "." or $_ eq ".."); if(-f "$cur_dir/$_" and look_ext("$_")) { push(@list, "$cur_dir/$_"); } elsif(-d "$cur_dir/$_") { push(@all_dir, "$cur_dir/$_"); } } } return @list; } ################################################################################ # look_ext($FILE) => Boolean # # Subrutin för att kolla om en angiven fil är en bild ################################################################################ sub look_ext { my @ext = ("jpg", "jpeg", "png", "bmp", "tif", "tiff", "gif"); foreach my $ext (@ext) { return 1 if(lc($_) =~ /$ext$/); } return 0; }

Placera skriptet i valfri mapp där det kan exekveras (glöm inte chmod +x resimg.pl heller).
Skriptet används då genom att köra:

resimg ExisterandeMapp/ Storlek [NyMapp]

NyMapp används bara ifall skriptet själv kommer att kopiera hela mappstrukturen. Som standard kopieras inte mappstrukturen men det kan enkelt göras genom att lägga till flaggan '-c', exempelvis:

resimg -c ExisterandeMapp/ Storlek NyMapp

Notera dock att det även går att manuellt skriva in det i filen att kopiering kan ske som standard. Ändra $copy till 1 istället för 0. Om $copy har ändrats manuellt i filen till 1 kommer -c istället innebära att mappstrukturen inte kopiera. Ställ in efter vad som passar dina behov.

OBS! Som standard kopieras mappstrukturen INTE!

Permalänk

Det ser ju helt fenomenalt ut! Grymt bra jobbat

Ser att du använder convert som jag gör. Då går det enkelt att direkt skapa en mindre kopia på detta vis:

convert BIG_PIC -auto-orient -resize NEX_SIZExNEW_SIZE NEW_FILE

Sen har jag lite svårt med Perl men ibland får jag filändelsen i versaler, kollar ditt script även dem?

Det handlar om 40Gb bilder så att undvika den initiala kopieringen kan vara värdefullt.

Permalänk
Medlem
Skrivet av Gräs-Mannen:

Det ser ju helt fenomenalt ut! Grymt bra jobbat

Ser att du använder convert som jag gör. Då går det enkelt att direkt skapa en mindre kopia på detta vis:

convert BIG_PIC -auto-orient -resize NEX_SIZExNEW_SIZE NEW_FILE

Den där varianten av convert låter intressant. Ser till att fixa det i nästa version

Skrivet av Gräs-Mannen:

Sen har jag lite svårt med Perl men ibland får jag filändelsen i versaler, kollar ditt script även dem?

Perl kan vara lite jobbigt ibland ja, dock är det det skriptspråk jag är mest insatt i. I subrutinen/funktionen look_ext() längst ned i koden kollar den efter filändelsen. Jag har använt funktionen lc() för filändelsen hos filerna så de ska alltid vara i gemener. Med andra ord, skriptet ska hantera både versaler och gemenr i filändelser.

Skrivet av Gräs-Mannen:

Det handlar om 40Gb bilder så att undvika den initiala kopieringen kan vara värdefullt.

40GB var inte riktigt vad jag hade väntat mig
Ska ha lite tid över imorgon också så kanske skriver om skriptet så att det inte gör onödiga kopior. Är det något ytterligare som kan vara bra att veta eller som önskas?

Permalänk

Det är nog allt

Permalänk
Medlem
Skrivet av Gräs-Mannen:

Det är nog allt

Har suttit och gjort en ny variant nu. Kod finns nedan och även på denna direktlänk.

Skriptet gör nu följande:

  • Skannar igenom den existerande mappen (kan/bör ej vara den man befinner sig i) och dess mappstruktur.

  • Skapar mappstrukturen i en ny mapp (i en som inte existerade innan skriptet starta).

  • Kopierar alla filer som ej är bilder till den nya mappstrukturen.

  • Konverterar alla bilder och sparar dem i den nya mappstrukturen.

  • Ger flashig output med vad som sker.

#!/usr/bin/perl use warnings; use strict; # Basvariabler my $dir; my $size; my $new_dir; # Listor för mapp- och filstruktur my @directories; my @files; my @images; # Kollar så argumentet för $size är en integer. if ($ARGV[1] && $ARGV[1] !~ /^-?\d+$/) { die("Error: Size argument is not an integer.\n"); } # Definerar $dir och $size, avslutar om argumenten inte räcker till. if ($ARGV[0] && $ARGV[1]) { $dir = $ARGV[0]; $dir =~ s/\/$//; $size = $ARGV[1]; } else { die("Error: Not enough sufficent arguments.\n\nUsage: resimg existing_dir new_size [new_dir]\n"); } # Definerar $new_dir, antingen till ARGV[2] eller ''$dir'_''$size'px if ($ARGV[2]) { $new_dir = $ARGV[2]; } else { $new_dir = $dir . "_" . $size . "px"; } # Kollar ifall $dir existerar, avslutar om den inte existerar. die("Error: Directory '$dir' does not exists.\n") unless (-d $dir); # Kollar ifall $new_dir existerar, avslutar om den existerar. die("Error: New directory '$new_dir' does already exists.\n") if (-d $new_dir); # Output print("[Information]\n"); print("Choosen directory: $dir\n"); print("New image size: $size px\n"); print("New directory: $new_dir\n"); print("\n[Process: Scanning directories]\n"); # Går igenom $dir och dess mappstruktur. # - Alla mappar sparas i @directories för senare behandling. # - Alla filer (ej bilder) sparas i @files för senare behandling. # - Alla bilder sparas i @images för senare behandling. my @all_dir = $dir; foreach my $current_dir (@all_dir) { # Öppnar $current_dir och placerar innehållet i @content_dir. opendir(FOLDER, $current_dir) or die("Error: Could not open directory '$current_dir'.\n"); my @content = readdir(FOLDER); closedir(FOLDER); # Går igenom @content_dir för att behandla innehållet. foreach my $current_item (@content) { # Ignorerar om det är mapparna '.' och '..'. next if ($current_item eq "." || $current_item eq ".."); # En temporär variabel för att hantera skapning av mappar. my $temp_dir = $current_dir; $temp_dir =~ s/^[^\/]+\///; if ($temp_dir eq $dir) { $temp_dir = ""; } else { $temp_dir = "/" . $temp_dir; } # Kollar om det är en mapp och i så fall skapar den nya mappen. if (-d "$current_dir/$current_item") { push(@all_dir, "$current_dir/$current_item"); push(@directories, "$temp_dir/$current_item"); } # Kollar om det är en fil. elsif (-f "$current_dir/$current_item") { # Kollar om det är en bildfil. if (look_ext($current_item)) { push(@images, "$temp_dir/$current_item"); } else { push(@files, "$temp_dir/$current_item"); } } } } # Sortering av innehåll för "snyggare" output @directories = sort(@directories); @files = sort(@files); @images = sort(@images); # Output print("Directories found: " . ($#directories + 2) . "\n"); print("Files found: " . ($#files + 1) . "\n"); print("Images found: " . ($#images + 1) . "\n"); # Skapa mappstruktur print("\n[Process: Creating directories]\n"); print("(1/" . ($#directories + 2) . ") Creating directory: $new_dir\n"); system("mkdir '$new_dir'"); my $i = 2; foreach my $directory (@directories) { print("($i/" . ($#directories + 2) . ") Creating directory: $new_dir$directory\n"); system("mkdir '$new_dir$directory'"); $i++; } # Utför alla filkopieringar print("\n[Process: Copying files]\n"); $i = 1; foreach my $file (@files) { print("($i/" . ($#files + 1) . ") Copying file: $dir$file => $new_dir$file\n"); system("cp '$dir$file' '$new_dir$file'"); } # Utför alla bildkonverteringar print("\n[Process: Converting images]\n"); $i = 1; foreach my $image (@images) { print("($i/" . ($#images + 1) . ") Converting image: $dir$image => $new_dir$image\n"); system("convert '$dir$image' -auto-orient -resize " . $size . "x" . $size . " '$new_dir$image'"); $i++; } # Avslutning print("\n[Conclusion]\n"); print("Directories created: " . ($#directories + 2) . "\n"); print("Files copied: " . ($#files + 1) . "\n"); print("Images converted: " . ($#images + 1) . "\n"); ################################################################################ # Subrutin för att kolla om en angiven fil är en bildfil. ################################################################################ sub look_ext { my @ext = ("jpg", "jpeg", "png", "bmp", "tif", "tiff", "gif"); foreach my $ext (@ext) { return 1 if (lc($_[0]) =~ /$ext$/); } return 0; }

Skriptet fungerar inte likadant som det gamla. I detta skript är rekursivitet alltid påslaget (går ej att ändra). Som tidigare behöver man inte ange mappnamn för den nya mappen utan användningen är till exempel:

resimg MinMapp 640

så skapas en mapp som heter MinMapp_640px. Annars anger man namn genom:

resimg MinMapp 640 NyMapp

Observera att NyMapp ej får existera innan skriptet körs. Ifall du glömmer hur skriptet används räcker det med att skriva:

resimg

för att en kort beskrivning ska presenteras (detsamma om det saknas argument).

Hoppas att det är tillräckligt för denna gång

Permalänk

Tusen tack! Ska testa det senare idag.

Permalänk
Skrivet av Kuufukuji:

Har suttit och gjort en ny variant nu. Kod finns nedan och även på denna direktlänk.

Skriptet gör nu följande:
...
Hoppas att det är tillräckligt för denna gång

Tusen tack. Scriptet funkar utomordentligt bra! Det enda jag kan komma på vore att den startar en konvertering per kärna *hint hint*... hahah