Jp2 batch converter
From OpenSimulator
(Difference between revisions)
m (→Code) |
m (Robot: Replacing 'OpenSim' to 'OpenSimulator', which is the precise name) |
||
(10 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 | #landscape or square, search for optimal X | ||
if ($imageX >= $imageY){ | if ($imageX >= $imageY){ | ||
$ar = sprintf("%.4f",$imageY / $imageX); | $ar = sprintf("%.4f",$imageY / $imageX); | ||
− | $optar = | + | $optar = &supportedAR($ar); |
$optX = &supportedXY($imageX); | $optX = &supportedXY($imageX); | ||
$optY = $optX * $optar; | $optY = $optX * $optar; | ||
Line 86: | Line 77: | ||
else { | else { | ||
$ar = sprintf("%.4f",$imageX / $imageY); | $ar = sprintf("%.4f",$imageX / $imageY); | ||
− | $optar = | + | $optar = &supportedAR($ar); |
$optY = &supportedXY($imageY); | $optY = &supportedXY($imageY); | ||
$optX = $optY * $optar; | $optX = $optY * $optar; | ||
Line 92: | Line 83: | ||
unless(($imageY==$optRes) && ($ar==$optar)) { | unless(($imageY==$optRes) && ($ar==$optar)) { | ||
print "\nResizing ($imageX\xx$imageY => $optX\xx$optY)..."; | print "\nResizing ($imageX\xx$imageY => $optX\xx$optY)..."; | ||
− | system("convert -resize ${optX}x${ | + | system("convert -resize ${optX}x${optY}! $rawname.$ext $rawname.$ext &>/dev/null"); |
print "Done"; | print "Done"; | ||
} | } | ||
− | + | } | |
if (($ext eq "jpg") || ($ext eq "jpeg")){ | if (($ext eq "jpg") || ($ext eq "jpeg")){ | ||
print "\nConverting jpg to valid openjpeg format..."; | print "\nConverting jpg to valid openjpeg format..."; | ||
Line 103: | Line 94: | ||
$ext="tga"; | $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"