Jp2 batch converter for windows
From OpenSimulator
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)
- The ImageMagick executables for windows. (www.imagemagick.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 Outsourcing Indonesia 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 # 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.