Jp2 batch converter
From OpenSimulator
(Difference between revisions)
(New page: #!/usr/bin/perl $iteration=1; foreach my $file(`ls *.jpg`) { chop($file); system("jasper --input $file --output $iteration.jp2 -T jp2;"); $iteration++; }) |
m (Robot: Replacing 'OpenSim' to 'OpenSimulator', which is the precise name) |
||
(28 intermediate revisions by 4 users not shown) | |||
Line 1: | Line 1: | ||
− | + | __NOTOC__ | |
− | + | {{Quicklinks}} | |
+ | <br /> | ||
− | + | == Description == | |
− | + | The jp2 files used by the Secondlife client, are actually j2k files. These can be encoded by image_to_j2k from openjpeg. The script identifies the image-resolution, and converts the image to a valid SL-resolution/aspect ratio. Subsequently it checks for jpg-files, and converts them to valid openjpeg input files if necessary. Valid openjpeg files are then converted to j2k fileformat, by image_to_j2k. At last the j2k file is renamed to jp2, and can be used as an secondlife texture. Use genassets.pl to generate an asset-set out of these files. | |
− | + | ||
− | + | == Code == | |
+ | <source lang="perl"> | ||
+ | #!/usr/bin/perl -s -U | ||
+ | # jp2batch.pl | ||
+ | # OpenSimulator jp2 texture preparation script | ||
+ | # Converts jpg/jpeg/bmp/tga files to valid jp2(jk2) files for SL | ||
+ | # Author: Phrearch | ||
+ | # Credits: Tedd1 | ||
+ | |||
+ | $dirs=0; | ||
+ | $files=0; | ||
+ | |||
+ | 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 | ||
+ | if (-d $name){ | ||
+ | print "Entering directory $name\n"; | ||
+ | &ScanDirectory($name); | ||
+ | next; | ||
+ | } | ||
+ | #jpg or jpeg | ||
+ | if ($name =~ /^(.*)\.(jpe?g|bmp|tga|tif|raw)$/){ | ||
+ | $rawname = $1; | ||
+ | $ext = lc($2); | ||
+ | $files++; | ||
+ | print "\nProcessing $name..."; | ||
+ | &Convert($rawname,$ext); | ||
+ | } | ||
} | } | ||
+ | } | ||
+ | |||
+ | sub Convert{ | ||
+ | my ($rawname, $ext) = @_; | ||
+ | my @imageid = split(/ /,`identify $rawname.$ext`); | ||
+ | my @imageXY = split('x',@imageid[2]); | ||
+ | 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){ | ||
+ | $ar = sprintf("%.4f",$imageY / $imageX); | ||
+ | $optar = &supportedAR($ar); | ||
+ | $optX = &supportedXY($imageX); | ||
+ | $optY = $optX * $optar; | ||
+ | #both aspectratio and resolution are correct | ||
+ | unless(($imageX==$optRes) && ($ar==$optar)) { | ||
+ | print "\nResizing ($imageX\xx$imageY => $optY\xx$optX)..."; | ||
+ | system(`convert -resize ${optX}x${optY}! $rawname.$ext $rawname.$ext &>/dev/null`); | ||
+ | print "Done"; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | #portrait, search for optimal Y | ||
+ | else { | ||
+ | $ar = sprintf("%.4f",$imageX / $imageY); | ||
+ | $optar = &supportedAR($ar); | ||
+ | $optY = &supportedXY($imageY); | ||
+ | $optX = $optY * $optar; | ||
+ | #Needs conversion | ||
+ | unless(($imageY==$optRes) && ($ar==$optar)) { | ||
+ | print "\nResizing ($imageX\xx$imageY => $optX\xx$optY)..."; | ||
+ | system("convert -resize ${optX}x${optY}! $rawname.$ext $rawname.$ext &>/dev/null"); | ||
+ | print "Done"; | ||
+ | } | ||
+ | } | ||
+ | if (($ext eq "jpg") || ($ext eq "jpeg")){ | ||
+ | print "\nConverting jpg to valid openjpeg format..."; | ||
+ | system("convert -format tga $rawname.$ext $rawname.tga &>/dev/null"); | ||
+ | system("rm $rawname.$ext &>/dev/null"); | ||
+ | print "Done"; | ||
+ | $ext="tga"; | ||
+ | } | ||
+ | print "\nCreating jp2 file..."; | ||
+ | system("image_to_j2k -i $rawname.$ext -o $rawname.j2k -r 20,10,1 &>/dev/null"); | ||
+ | system("mv $rawname.j2k $rawname.jp2 &>/dev/null"); | ||
+ | system("rm $rawname.$ext &>/dev/null"); | ||
+ | print "Done\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 > 0 ){ | ||
+ | print "Processing ".@ARGV[0]."...\n"; | ||
+ | &ScanDirectory(@ARGV[0]); | ||
+ | print "\nDirectories scanned:$dirs\nFiles processed:$files\n" ; | ||
+ | } | ||
+ | else { | ||
+ | print "Provide a directory to process...\n"; | ||
+ | } | ||
+ | </source> | ||
+ | |||
+ | == Usage == | ||
+ | * Install OpenJPEG svn (if you have trouble compiling, you could try the binaries on their site) | ||
+ | svn co http://www.openjpeg.org/svn/trunk | ||
+ | cd trunk | ||
+ | mkdir bin | ||
+ | cd bin | ||
+ | cmake .. -DBUILD_EXAMPLES:BOOL=ON | ||
+ | make | ||
+ | make install | ||
+ | PATH=/usr/local/bin:$PATH | ||
+ | * Make sure that the binaries image_to_j2k and j2k_to_image can be executed from anywhere | ||
+ | Add /usr/local/bin to /etc/profile for a permanent path. | ||
+ | |||
+ | * Put the code in a file named jp2batch.pl, and copy it to the /opt/opensim/scripts directory. The script uses a directory as parameter: | ||
+ | perl jp2batch.pl "/some directory/with/images" |
Latest revision as of 22:40, 3 March 2012
[edit] Description
The jp2 files used by the Secondlife client, are actually j2k files. These can be encoded by image_to_j2k from openjpeg. The script identifies the image-resolution, and converts the image to a valid SL-resolution/aspect ratio. Subsequently it checks for jpg-files, and converts them to valid openjpeg input files if necessary. Valid openjpeg files are then converted to j2k fileformat, by image_to_j2k. At last the j2k file is renamed to jp2, and can be used as an secondlife texture. Use genassets.pl to generate an asset-set out of these files.
[edit] Code
#!/usr/bin/perl -s -U # jp2batch.pl # OpenSimulator jp2 texture preparation script # Converts jpg/jpeg/bmp/tga files to valid jp2(jk2) files for SL # Author: Phrearch # Credits: Tedd1 $dirs=0; $files=0; 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 if (-d $name){ print "Entering directory $name\n"; &ScanDirectory($name); next; } #jpg or jpeg if ($name =~ /^(.*)\.(jpe?g|bmp|tga|tif|raw)$/){ $rawname = $1; $ext = lc($2); $files++; print "\nProcessing $name..."; &Convert($rawname,$ext); } } } sub Convert{ my ($rawname, $ext) = @_; my @imageid = split(/ /,`identify $rawname.$ext`); my @imageXY = split('x',@imageid[2]); 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){ $ar = sprintf("%.4f",$imageY / $imageX); $optar = &supportedAR($ar); $optX = &supportedXY($imageX); $optY = $optX * $optar; #both aspectratio and resolution are correct unless(($imageX==$optRes) && ($ar==$optar)) { print "\nResizing ($imageX\xx$imageY => $optY\xx$optX)..."; system(`convert -resize ${optX}x${optY}! $rawname.$ext $rawname.$ext &>/dev/null`); print "Done"; } } #portrait, search for optimal Y else { $ar = sprintf("%.4f",$imageX / $imageY); $optar = &supportedAR($ar); $optY = &supportedXY($imageY); $optX = $optY * $optar; #Needs conversion unless(($imageY==$optRes) && ($ar==$optar)) { print "\nResizing ($imageX\xx$imageY => $optX\xx$optY)..."; system("convert -resize ${optX}x${optY}! $rawname.$ext $rawname.$ext &>/dev/null"); print "Done"; } } if (($ext eq "jpg") || ($ext eq "jpeg")){ print "\nConverting jpg to valid openjpeg format..."; system("convert -format tga $rawname.$ext $rawname.tga &>/dev/null"); system("rm $rawname.$ext &>/dev/null"); print "Done"; $ext="tga"; } print "\nCreating jp2 file..."; system("image_to_j2k -i $rawname.$ext -o $rawname.j2k -r 20,10,1 &>/dev/null"); system("mv $rawname.j2k $rawname.jp2 &>/dev/null"); system("rm $rawname.$ext &>/dev/null"); print "Done\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 > 0 ){ print "Processing ".@ARGV[0]."...\n"; &ScanDirectory(@ARGV[0]); print "\nDirectories scanned:$dirs\nFiles processed:$files\n" ; } else { print "Provide a directory to process...\n"; }
[edit] Usage
- Install OpenJPEG svn (if you have trouble compiling, you could try the binaries on their site)
svn co http://www.openjpeg.org/svn/trunk cd trunk mkdir bin cd bin cmake .. -DBUILD_EXAMPLES:BOOL=ON make make install PATH=/usr/local/bin:$PATH
- Make sure that the binaries image_to_j2k and j2k_to_image can be executed from anywhere
Add /usr/local/bin to /etc/profile for a permanent path.
- Put the code in a file named jp2batch.pl, and copy it to the /opt/opensim/scripts directory. The script uses a directory as parameter:
perl jp2batch.pl "/some directory/with/images"