Jp2 batch converter
From OpenSimulator
(Difference between revisions)
m (Robot: Replacing 'OpenSim' to 'OpenSimulator', which is the precise name) |
|||
(8 intermediate revisions by 4 users not shown) | |||
Line 1: | Line 1: | ||
− | ==Description== | + | __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. | 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== | + | == 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== | + | == Usage == |
* Install OpenJPEG svn (if you have trouble compiling, you could try the binaries on their site) | * Install OpenJPEG svn (if you have trouble compiling, you could try the binaries on their site) | ||
svn co http://www.openjpeg.org/svn/trunk | svn co http://www.openjpeg.org/svn/trunk | ||
Line 143: | Line 154: | ||
make | make | ||
make install | make install | ||
+ | PATH=/usr/local/bin:$PATH | ||
* Make sure that the binaries image_to_j2k and j2k_to_image can be executed from anywhere | * 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 | + | * 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 | + | 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"