Jp2 batch converter
From OpenSimulator
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
#!/usr/bin/perl -s -U
# jp2batch.pl
# OpenSim 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${opt}Y! $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,2048.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;
}
&ScanDirectory(".");
print "\nDirectories scanned:$dirs\nFiles processed:$files\n" ;
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
- Make sure that the binaries image_to_j2k and j2k_to_image can be executed from anywhere
- Put the code in a file named jp2batch.pl, and copy it to the root-directory where your jpg-wannabe-textures are. Call the script:
perl jp2batch.pl