Jp2 batch converter for windows

From OpenSimulator

Revision as of 01:29, 25 March 2013 by Butoijoh (Talk | contribs)

Jump to: navigation, search


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 ...
  • 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
# OpenSimulator 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