Jp2 batch converter for windows

From OpenSimulator

(Difference between revisions)
Jump to: navigation, search
(Code)
Line 46: Line 46:
 
$delete=0;
 
$delete=0;
  
sub ScanDirectory
+
sub Scan {
{
+
    my ($dir) = @_;
 +
    local ($substr);
 +
    $substr = substr($dir, -1);
 +
    if(($substr eq "/") || ($substr eq "\\")) {
 +
        $dir = substr($dir, 0, -1);
 +
    }
 +
   
 +
    if (-d $dir) {
 +
        &ScanDirectory($dir);
 +
        print "Directories scanned:$dirs\nFiles processed:$files\n";
 +
    }
 +
    else {
 +
        print "Non-existent directory $dir\n";
 +
    }
 +
}
 +
sub ScanDirectory {
 
     my ($workdir) = @_;
 
     my ($workdir) = @_;
 
     local (@names);
 
     local (@names);
Line 54: Line 69:
 
     @names = readdir(DIR) or die "Unable to read $workdir:$!\n";
 
     @names = readdir(DIR) or die "Unable to read $workdir:$!\n";
 
     closedir(DIR);
 
     closedir(DIR);
     foreach my $tmpName (@names)
+
     foreach my $tmpName (@names) {
    {
+
 
         my $name = $workdir."\\".$tmpName;
 
         my $name = $workdir."\\".$tmpName;
 
         #\. or \.. in directory
 
         #\. or \.. in directory
         if ($tmpName =~ /^\.\.?$/)
+
         if ($tmpName =~ /^\.\.?$/) {
        {
+
 
             next;
 
             next;
 
         }
 
         }
 
         #directory
 
         #directory
         elsif (-d $name)
+
         elsif (-d $name) {
        {
+
 
             print "Entering directory $name\n";
 
             print "Entering directory $name\n";
 
             &ScanDirectory($name);
 
             &ScanDirectory($name);
Line 70: Line 82:
 
         }
 
         }
 
         #jpg or jpeg
 
         #jpg or jpeg
         elsif ($name =~ /^(.*)\.(jpe?g|bmp|tga|tif|raw)$/)
+
         elsif ($tmpName =~ /^(.*)\.([jJ][pP][eE]?[gG]|[bB][mM][pP]|[tT][gG][aA]|[tT][iI][fF][fF]?|[rR][aA][wW])$/) {
        {
+
             $filename = $1;
             $rawname = $1;
+
 
             $ext = lc($2);
 
             $ext = lc($2);
 +
            $rawname = $workdir."\\".$filename;
 
             $files++;
 
             $files++;
             print "\n----- Processing $name... -----";
+
             print "\n----- Processing $filename.$ext -----";
             &Convert($rawname,$ext,$delete);
+
             &Convert($rawname,$ext,$filename);
 
         }
 
         }
 
     }
 
     }
 
}
 
}
sub Convert
+
sub Convert {
{
+
     my ($rawname, $ext, $filename) = @_;
     my ($rawname, $ext) = @_;
+
 
     my @imageXY = split('x',`identify -format "%wx%h" "$rawname.$ext"`);  
 
     my @imageXY = split('x',`identify -format "%wx%h" "$rawname.$ext"`);  
 
     my $imageX = pop(@imageXY);
 
     my $imageX = pop(@imageXY);
Line 92: Line 103:
  
 
     #landscape or square, search for optimal X
 
     #landscape or square, search for optimal X
     if (($imageX >= $imageY) && ($imageX != 0))
+
     if (($imageX >= $imageY) && ($imageX != 0)) {
    {
+
 
         $ar = sprintf("%.4f",$imageY / $imageX);
 
         $ar = sprintf("%.4f",$imageY / $imageX);
 
         $optar =  &supportedAR($ar);
 
         $optar =  &supportedAR($ar);
Line 99: Line 109:
 
         $optY = $optX * $optar;
 
         $optY = $optX * $optar;
 
         #both aspectratio and resolution are correct
 
         #both aspectratio and resolution are correct
         if(($imageX!=$optRes) || ($ar!=$optar))
+
         if(($imageX!=$optRes) || ($ar!=$optar)) {
        {
+
 
             print "\nResizing ($imageX\xx$imageY => $optY\xx$optX)... ";
 
             print "\nResizing ($imageX\xx$imageY => $optY\xx$optX)... ";
 
             system("imconvert -resize ${optX}x${optY}! \"$rawname.$ext\" \"$rawname.$ext\"");
 
             system("imconvert -resize ${optX}x${optY}! \"$rawname.$ext\" \"$rawname.$ext\"");
Line 107: Line 116:
 
     }
 
     }
 
     #portrait, search for optimal Y
 
     #portrait, search for optimal Y
     elsif($imageY != 0)
+
     elsif($imageY != 0) {
    {
+
 
         $ar = sprintf("%.4f",$imageX / $imageY);
 
         $ar = sprintf("%.4f",$imageX / $imageY);
 
         $optar =  &supportedAR($ar);
 
         $optar =  &supportedAR($ar);
Line 114: Line 122:
 
         $optX = $optY * $optar;
 
         $optX = $optY * $optar;
 
         #Needs conversion
 
         #Needs conversion
         if(($imageY!=$optRes) || ($ar!=$optar))
+
         if(($imageY!=$optRes) || ($ar!=$optar)) {
        {
+
 
             print "\nResizing ($imageX\xx$imageY => $optX\xx$optY)... ";
 
             print "\nResizing ($imageX\xx$imageY => $optX\xx$optY)... ";
 
             system("imconvert -resize ${optX}x${optY}! \"$rawname.$ext\" \"$rawname.$ext\"");
 
             system("imconvert -resize ${optX}x${optY}! \"$rawname.$ext\" \"$rawname.$ext\"");
Line 122: Line 129:
 
     }
 
     }
 
      
 
      
     if (($ext eq "jpg") || ($ext eq "jpeg"))
+
     if ($ext =~ /^(?:[jJ][pP][eE]?[gG])$/) {
    {
+
         print "\nConverting $ext to valid openjpeg (tga) format to handle... ";
         print "\nConverting jpg to valid openjpeg (tga) format to handle... ";
+
 
         system("imconvert -format tga \"$rawname.$ext\" \"$rawname.tga\"");
 
         system("imconvert -format tga \"$rawname.$ext\" \"$rawname.tga\"");
 
         print "Done\n";
 
         print "Done\n";
         if($delete==1)
+
         if($delete==1) {
        {
+
 
             print "\nDeleting old file... ";
 
             print "\nDeleting old file... ";
 
             system("del \"$rawname.$ext\"");
 
             system("del \"$rawname.$ext\"");
 
             print "Done\n";
 
             print "Done\n";
 +
            $delete=3;
 +
        }
 +
        else {
 +
            $delete=2;
 
         }
 
         }
 
         $ext="tga";
 
         $ext="tga";
        $delete=2;
 
 
     }
 
     }
     print "\nCreating .jp2 (jpeg2000) file... ";
+
     print "\nCreating .j2k (jpeg2000) file... ";
     system("image_to_j2k -i \"$rawname.$ext\" -o \"$rawname.jp2\" -r 20,10,1");
+
     system("image_to_j2k -i \"$rawname.$ext\" -o \"$rawname.j2k\" -r 20,10,1");
     print "Done";
+
     print "Done\n";
     if($delete>0)
+
   
    {
+
    print "\nRenaming .j2k file to .jp2... ";
         if($delete==1)
+
    # We cannot rename if there is already such an file, so find the file-number that CAN be named to
        {
+
    if(-e "$rawname.jp2") {
             print "\nDeleting old file... ";
+
        $num = 1;
 +
        while(-e "$rawname $num.jp2") {
 +
            $num++;
 +
        }
 +
        system("rename \"$rawname.j2k\" \"$filename $num.jp2\"");
 +
    }
 +
    print "Done\n";
 +
   
 +
     if($delete>0) {
 +
         if($delete>1) {
 +
             print "Deleting temporary .tga file... ";
 
             system("del \"$rawname.$ext\"");
 
             system("del \"$rawname.$ext\"");
 
             print "Done\n";
 
             print "Done\n";
 +
            if($delete==3) {
 +
                $delete=1;
 +
            }
 +
            else {
 +
                $delete=0;
 +
            }
 
         }
 
         }
         elsif($delete==2)
+
         else {
        {
+
             print "Deleting old file... ";
             print "\nDeleting temporary .tga file... ";
+
 
             system("del \"$rawname.$ext\"");
 
             system("del \"$rawname.$ext\"");
 
             print "Done\n";
 
             print "Done\n";
Line 156: Line 179:
 
     print "--------------------------------\n";
 
     print "--------------------------------\n";
 
}
 
}
sub supportedAR
+
sub supportedAR {
{
+
 
     my ($ar) = @_;
 
     my ($ar) = @_;
 
     my @arReference=(1.0,0.5,0.25,0.125,0.0625);
 
     my @arReference=(1.0,0.5,0.25,0.125,0.0625);
Line 164: Line 186:
 
     my $arDiv;
 
     my $arDiv;
 
     #Get optimal aspect ratio
 
     #Get optimal aspect ratio
     foreach (@arReference)
+
     foreach (@arReference) {
    {
+
 
         $arDiv=abs($ar-$_);
 
         $arDiv=abs($ar-$_);
         if($arDiv < $arDivTemp)
+
         if($arDiv < $arDivTemp) {
        {
+
 
             $arDivTemp=$arDiv;
 
             $arDivTemp=$arDiv;
 
             $arOptimal=$_;
 
             $arOptimal=$_;
Line 175: Line 195:
 
     return $arOptimal;
 
     return $arOptimal;
 
}   
 
}   
sub supportedXY
+
sub supportedXY {
{
+
 
     my ($res) = @_;
 
     my ($res) = @_;
 
     my @resReference=(64.0,128.0,256.0,512.0,1024.0);
 
     my @resReference=(64.0,128.0,256.0,512.0,1024.0);
Line 183: Line 202:
 
     my $resDiv;
 
     my $resDiv;
 
     #Get optimal axis resolution
 
     #Get optimal axis resolution
     foreach (@resReference)
+
     foreach (@resReference) {
    {
+
 
         $resDiv=abs($res-$_);
 
         $resDiv=abs($res-$_);
         if($resDiv < $resDivTemp)
+
         if($resDiv < $resDivTemp) {
        {
+
 
             $resDivTemp=$resDiv;
 
             $resDivTemp=$resDiv;
 
             $resOptimal=$_;
 
             $resOptimal=$_;
Line 194: Line 211:
 
     return $resOptimal;
 
     return $resOptimal;
 
}  
 
}  
if ( @ARGV > 1 )
+
if (@ARGV>1) {
{
+
     if((@ARGV[0] eq "/D") || (@ARGV[0] eq "/d")) {
     if((@ARGV[0] eq "/D") || (@ARGV[0] eq "/d"))
+
         print "Processing ".@ARGV[1]."... (deleting old files) \n\n";
    {
+
         print "Processing ".@ARGV[1]."... (deleting old files) \n";
+
 
         $delete = 1;
 
         $delete = 1;
         &ScanDirectory(@ARGV[1],1);
+
         &Scan(@ARGV[1]);
        print "\nDirectories scanned:$dirs\nFiles processed:$files\n";
+
 
     }
 
     }
     elsif((@ARGV[1] eq "/D") || (@ARGV[1] eq "/d"))
+
     elsif((@ARGV[1] eq "/D") || (@ARGV[1] eq "/d")) {
    {
+
         print "Processing ".@ARGV[0]."... (deleting old files) \n\n";
         print "Processing ".@ARGV[0]."... (deleting old files) \n";
+
 
         $delete = 1;
 
         $delete = 1;
         &ScanDirectory(@ARGV[0]);
+
         &Scan(@ARGV[0]);
        print "\nDirectories scanned:$dirs\nFiles processed:$files\n";
+
 
     }
 
     }
     else
+
     else {
    {
+
 
         print "Syntax error\n";
 
         print "Syntax error\n";
 
         print "Provide just one directory argument, optionally with a /D argument...\n";
 
         print "Provide just one directory argument, optionally with a /D argument...\n";
 
     }
 
     }
 
}
 
}
elsif ( @ARGV > 0 )
+
elsif (@ARGV>0) {
{
+
     if((@ARGV[0] eq "help") || (@ARGV[0] eq "?")) {
     if((@ARGV[0] eq "help") || (@ARGV[0] eq "?"))
+
         print "\nBatch convert images to opensim-compatible .jp2 files\nWorks for: .jpg/.jpeg, .bmp, .tga, .tif/.tiff or .raw files\n\n\n";
    {
+
         print "\nBatch convert images to opensim-compatible .jp2 files\n\n\n";
+
 
         print "perl jp2batch.pl [/D] [station:][path]dir\n\n\n";
 
         print "perl jp2batch.pl [/D] [station:][path]dir\n\n\n";
 
         print "  dir      Directory (and sub-directories) to search for image files.\n";
 
         print "  dir      Directory (and sub-directories) to search for image files.\n";
Line 233: Line 242:
 
         print "    image_to_j2k.exe\n\n\n";
 
         print "    image_to_j2k.exe\n\n\n";
 
     }
 
     }
     elsif((@ARGV[1] eq "/D") || (@ARGV[1] eq "/d"))
+
     elsif((@ARGV[1] eq "/D") || (@ARGV[1] eq "/d")) {
    {
+
 
         print "Syntax error\n";
 
         print "Syntax error\n";
 
         print "You must provide a directory to process, optionally with a /D argument...\n";
 
         print "You must provide a directory to process, optionally with a /D argument...\n";
 
     }
 
     }
     else
+
     else {
    {
+
         print "Processing ".@ARGV[0]."...\n\n";
         print "Processing ".@ARGV[0]."...\n";
+
 
         $delete = 0;
 
         $delete = 0;
         &ScanDirectory(@ARGV[0]);
+
         &Scan(@ARGV[0]);
        print "\nDirectories scanned:$dirs\nFiles processed:$files\n";
+
 
     }
 
     }
 
}
 
}
else
+
else {
{
+
 
     print "Syntax error\n";
 
     print "Syntax error\n";
 
     print "Provide a directory to process, optionally with '/D' argument...\n";
 
     print "Provide a directory to process, optionally with '/D' argument...\n";

Revision as of 02:16, 21 August 2008

Contents

Description

For how, why and where it is made for: please refer to the wikipage of the original script.

This is a modification of that script to make the system commands work on windows systems. Also a helpful /help explanation and optional /D command to delete the old files is added.

Note: these are some quick adjustments to the original, it may or may not work, depending on your setup. It did work here.

Usage

Dependencies

  • This script is a perl script, so you first should go and install that. (www.perl.org)

Please note that the 'convert.exe' executable conflicts with the FAT-to-NTFS batch command of windows. This script will therefor seek a 'imconvert.exe' file in the PATH. Please rename it, or adjust the lines that start with:

system("imconvert ...
  • Openjpegs J2K Codec executables, more specifically: image_to_j2k.exe. (www.openjpeg.org)
  • References to all executables in the PATH environment variable.

This can be set trough Right-click My Computer->Properties: Advanced tab->Environment variables.

Arguments

The script takes 2 arguments

  • An optional /D argument, if added the script will also delete the old image files
  • A required directory specified.
  • Or, you could start it with a /help command, which gives about the same info as this page.

Running

Execute this from command prompt, optionally adding a /D argument for also deleting the source images.

perl jp2batch.pl /D "c:\directory\with\images\"

Code

# jp2batch.pl
# OpenSim jp2 texture preparation script (for windows)
# Converts jpg/jpeg/bmp/tga files to valid jp2(jk2) files for SL
# Author: Phrearch, modified by Jeroen Waisman for Windows systems
# Credits: Tedd1, Phrearch
 
$dirs=0;
$files=0;
$delete=0;
 
sub Scan {
    my ($dir) = @_;
    local ($substr);
    $substr = substr($dir, -1);
    if(($substr eq "/") || ($substr eq "\\")) {
        $dir = substr($dir, 0, -1);
    }
 
    if (-d $dir) {
        &ScanDirectory($dir);
        print "Directories scanned:$dirs\nFiles processed:$files\n";
    }
    else {
        print "Non-existent directory $dir\n";
    }
}
sub ScanDirectory {
    my ($workdir) = @_;
    local (@names);
    $dirs++;
    opendir(DIR, $workdir) or die "Unable to open $workdir:$!\n";
    @names = readdir(DIR) or die "Unable to read $workdir:$!\n";
    closedir(DIR);
    foreach my $tmpName (@names) {
        my $name = $workdir."\\".$tmpName;
        #\. or \.. in directory
        if ($tmpName =~ /^\.\.?$/) {
            next;
        }
        #directory
        elsif (-d $name) {
            print "Entering directory $name\n";
            &ScanDirectory($name);
            next;
        }	
        #jpg or jpeg
        elsif ($tmpName =~ /^(.*)\.([jJ][pP][eE]?[gG]|[bB][mM][pP]|[tT][gG][aA]|[tT][iI][fF][fF]?|[rR][aA][wW])$/) {
            $filename = $1;
            $ext = lc($2);
            $rawname = $workdir."\\".$filename;
            $files++;
            print "\n----- Processing $filename.$ext -----";
            &Convert($rawname,$ext,$filename);
        }
    }
}
sub Convert {
    my ($rawname, $ext, $filename) = @_;
    my @imageXY = split('x',`identify -format "%wx%h" "$rawname.$ext"`); 
    my $imageX = pop(@imageXY);
    my $imageY = pop(@imageXY);
    my $optX;
    my $optY;
    my $ar;
    my $optar;
 
    #landscape or square, search for optimal X
    if (($imageX >= $imageY) && ($imageX != 0)) {
        $ar = sprintf("%.4f",$imageY / $imageX);
        $optar =  &supportedAR($ar);
        $optX = &supportedXY($imageX);
        $optY = $optX * $optar;
        #both aspectratio and resolution are correct
        if(($imageX!=$optRes) || ($ar!=$optar)) {
            print "\nResizing ($imageX\xx$imageY => $optY\xx$optX)... ";
            system("imconvert -resize ${optX}x${optY}! \"$rawname.$ext\" \"$rawname.$ext\"");
            print "Done\n";
        }
    }
    #portrait, search for optimal Y
    elsif($imageY != 0) {
        $ar = sprintf("%.4f",$imageX / $imageY);
        $optar =  &supportedAR($ar);
        $optY = &supportedXY($imageY);
        $optX = $optY * $optar;
        #Needs conversion
        if(($imageY!=$optRes) || ($ar!=$optar)) {
            print "\nResizing ($imageX\xx$imageY => $optX\xx$optY)... ";
            system("imconvert -resize ${optX}x${optY}! \"$rawname.$ext\" \"$rawname.$ext\"");
            print "Done\n";
        }
    }
 
    if ($ext =~ /^(?:[jJ][pP][eE]?[gG])$/) {
        print "\nConverting $ext to valid openjpeg (tga) format to handle... ";
        system("imconvert -format tga \"$rawname.$ext\" \"$rawname.tga\"");
        print "Done\n";
        if($delete==1) {
            print "\nDeleting old file... ";
            system("del \"$rawname.$ext\"");
            print "Done\n";
            $delete=3;
        }
        else {
            $delete=2;
        }
        $ext="tga";
    }
    print "\nCreating .j2k (jpeg2000) file... ";
    system("image_to_j2k -i \"$rawname.$ext\" -o \"$rawname.j2k\" -r 20,10,1");
    print "Done\n";
 
    print "\nRenaming .j2k file to .jp2... ";
    # We cannot rename if there is already such an file, so find the file-number that CAN be named to
    if(-e "$rawname.jp2") {
        $num = 1;
        while(-e "$rawname $num.jp2") {
            $num++;
        }
        system("rename \"$rawname.j2k\" \"$filename $num.jp2\"");
    }
    print "Done\n";
 
    if($delete>0) {
        if($delete>1) {
            print "Deleting temporary .tga file... ";
            system("del \"$rawname.$ext\"");
            print "Done\n";
            if($delete==3) {
                $delete=1;
            }
            else {
                $delete=0;
            }
        }
        else {
            print "Deleting old file... ";
            system("del \"$rawname.$ext\"");
            print "Done\n";
        }
    }
    print "--------------------------------\n";
}
sub supportedAR {
    my ($ar) = @_;
    my @arReference=(1.0,0.5,0.25,0.125,0.0625);
    my $arOptimal;
    my $arDivTemp=1.0;
    my $arDiv;
    #Get optimal aspect ratio
    foreach (@arReference) {
        $arDiv=abs($ar-$_);
        if($arDiv < $arDivTemp) {
            $arDivTemp=$arDiv;
            $arOptimal=$_;
        }
    }
    return $arOptimal;
}  
sub supportedXY {
    my ($res) = @_;
    my @resReference=(64.0,128.0,256.0,512.0,1024.0);
    my $resOptimal;
    my $resDivTemp=4096.0;
    my $resDiv;
    #Get optimal axis resolution
    foreach (@resReference) {
        $resDiv=abs($res-$_);
        if($resDiv < $resDivTemp) {
            $resDivTemp=$resDiv;
            $resOptimal=$_;
        }
    }
    return $resOptimal;
} 
if (@ARGV>1) {
    if((@ARGV[0] eq "/D") || (@ARGV[0] eq "/d")) {
        print "Processing ".@ARGV[1]."... (deleting old files) \n\n";
        $delete = 1;
        &Scan(@ARGV[1]);
    }
    elsif((@ARGV[1] eq "/D") || (@ARGV[1] eq "/d")) {
        print "Processing ".@ARGV[0]."... (deleting old files) \n\n";
        $delete = 1;
        &Scan(@ARGV[0]);
    }
    else {
        print "Syntax error\n";
        print "Provide just one directory argument, optionally with a /D argument...\n";
    }
}
elsif (@ARGV>0) {
    if((@ARGV[0] eq "help") || (@ARGV[0] eq "?")) {
        print "\nBatch convert images to opensim-compatible .jp2 files\nWorks for: .jpg/.jpeg, .bmp, .tga, .tif/.tiff or .raw files\n\n\n";
        print "perl jp2batch.pl [/D] [station:][path]dir\n\n\n";
        print "  dir       Directory (and sub-directories) to search for image files.\n";
        print "  -D        If provided, old files will be deleted.\n\n\n\n\n";
        print "Dependencies, these executables should be available in the PATH or directory of the script.\n\n";
        print "  ImageMagick library functions: (note that I renamed one executable)\n";
        print "  Available at http://www.imagemagick.org/\n\n";
        print "    imconvert.exe       originaly named convert.exe, but renamed due to a Windows batch-command conflict.\n";
        print "    identify.exe\n\n\n";
        print "  OpenJpeg2000 library's J2K Codec: \n\n";
        print "  Available at http://www.openjpeg.org/\n";
        print "    image_to_j2k.exe\n\n\n";
    }
    elsif((@ARGV[1] eq "/D") || (@ARGV[1] eq "/d")) {
        print "Syntax error\n";
        print "You must provide a directory to process, optionally with a /D argument...\n";
    }
    else {
        print "Processing ".@ARGV[0]."...\n\n";
        $delete = 0;
        &Scan(@ARGV[0]);
    }
}
else {
    print "Syntax error\n";
    print "Provide a directory to process, optionally with '/D' argument...\n";
}

Credits

Ofcourse almost all credit goes to the original author of this script. I just adjusted a few commands to make it work on Windows systems.

Personal tools
General
About This Wiki