Jp2 batch converter

From OpenSimulator

(Difference between revisions)
Jump to: navigation, search
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 ==
#!/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
+
# OpenSimulator 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${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{
+
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(@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 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"

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"
Personal tools
General
About This Wiki