Jp2 batch converter

From OpenSimulator

(Difference between revisions)
Jump to: navigation, search
m (Code)
Line 3: Line 3:
  
 
==Code==
 
==Code==
#!/usr/bin/perl -s -U
+
<source lang="perl">
# jp2batch.pl
+
#!/usr/bin/perl -s -U
# OpenSim jp2 texture preparation script
+
# jp2batch.pl
# Converts jpg/jpeg/bmp/tga files to valid jp2(jk2) files for SL
+
# OpenSim jp2 texture preparation script
# Author: Phrearch
+
# Converts jpg/jpeg/bmp/tga files to valid jp2(jk2) files for SL
# Credits: Tedd1
+
# Author: Phrearch
+
# Credits: Tedd1
$dirs=0;
+
 
$files=0;
+
$dirs=0;
+
$files=0;
sub ScanDirectory{
+
 
  my ($workdir) = @_;
+
sub ScanDirectory{
  local (@names);
+
  my ($workdir) = @_;
  $dirs++;
+
  local (@names);
opendir(DIR, $workdir) or die "Unable to open $workdir:$!\n";
+
  $dirs++;
@names = readdir(DIR) or die "Unable to read $workdir:$!\n";
+
opendir(DIR, $workdir) or die "Unable to open $workdir:$!\n";
closedir(DIR);
+
@names = readdir(DIR) or die "Unable to read $workdir:$!\n";
foreach my $tmpName (@names){
+
closedir(DIR);
my $name = $workdir."/".$tmpName;
+
foreach my $tmpName (@names){
#\. or \.. in directory
+
my $name = $workdir."/".$tmpName;
if ($tmpName =~ /^\.\.?$/){
+
#\. or \.. in directory
next;
+
if ($tmpName =~ /^\.\.?$/){
}
+
next;
#directory
+
}
if (-d $name){
+
#directory
print "Entering directory $name\n";
+
if (-d $name){
&ScanDirectory($name);
+
print "Entering directory $name\n";
next;
+
&ScanDirectory($name);
}
+
next;
#jpg or jpeg
+
}
if ($name =~ /^(.*)\.(jpe?g|bmp|tga|tif|raw)$/){
+
#jpg or jpeg
$rawname = $1;
+
if ($name =~ /^(.*)\.(jpe?g|bmp|tga|tif|raw)$/){
$ext = lc($2);
+
$rawname = $1;
$files++;
+
$ext = lc($2);
print "\nProcessing $name...";
+
$files++;
&Convert($rawname,$ext);
+
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{
+
sub Convert{
my ($ar) = @_;
+
my ($rawname, $ext) = @_;
my @arReference=(1.0,0.5,0.25,0.125,0.0625);
+
my @imageid = split(/ /,`identify $rawname.$ext`);
my $arOptimal;
+
my @imageXY = split('x',@imageid[2]);
my $arDivTemp=1.0;
+
my $imageX = pop(@imageXY);
my $arDiv;
+
my $imageY = pop(@imageXY);
#Get optimal aspect ratio
+
my $optX;
foreach (@arReference){
+
my $optY;
$arDiv=abs($ar-$_);
+
my $ar;
if($arDiv < $arDivTemp) {
+
my $optar;
$arDivTemp=$arDiv;
+
 
$arOptimal=$_;
+
 
}
+
#landscape or square, search for optimal X
}
+
if ($imageX >= $imageY){
return $arOptimal;
+
$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";
 +
}
 +
}
 
   
 
   
sub supportedXY{
+
#portrait, search for optimal Y
my ($res) = @_;
+
else {
my @resReference=(64.0,128.0,256.0,512.0,1024.0,2048.0);
+
$ar = sprintf("%.4f",$imageX / $imageY);
  my $resOptimal;
+
$optar = &supportedAR($ar);
my $resDivTemp=4096.0;
+
$optY = &supportedXY($imageY);
my $resDiv;
+
$optX = $optY * $optar;
#Get optimal axis resolution
+
#Needs conversion
foreach (@resReference){
+
unless(($imageY==$optRes) && ($ar==$optar)) {
  $resDiv=abs($res-$_);
+
print "\nResizing ($imageX\xx$imageY => $optX\xx$optY)...";
if($resDiv < $resDivTemp) {
+
system("convert -resize ${optX}x${optY}! $rawname.$ext $rawname.$ext &>/dev/null");
$resDivTemp=$resDiv;
+
print "Done";
$resOptimal=$_;
+
}
}
+
 
  }
 
  }
  return $resOptimal;
+
if (($ext eq "jpg") || ($ext eq "jpeg")){
}  
+
print "\nConverting jpg to valid openjpeg format...";
+
system("convert -format tga $rawname.$ext $rawname.tga &>/dev/null");
&ScanDirectory(".");
+
system("rm $rawname.$ext &>/dev/null");
print "\nDirectories scanned:$dirs\nFiles processed:$files\n" ;
+
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(".");
 +
print "\nDirectories scanned:$dirs\nFiles processed:$files\n" ;
 +
}
 +
else {
 +
print "Provide a directory to process...\n";
 +
}
  
 
==Usage==
 
==Usage==
Line 142: Line 149:
 
  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 root-directory where your jpg-wannabe-textures are. Call the script:
+
* 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

Revision as of 04:05, 13 May 2008

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${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(".");
print "\nDirectories scanned:$dirs\nFiles processed:$files\n" ;
}
else {
print "Provide a directory to process...\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
 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
Personal tools
General
About This Wiki