Jp2 batch converter

From OpenSimulator

(Difference between revisions)
Jump to: navigation, search
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:
==Description==
+
__NOTOC__
The jp2 files used by the Secondlife client, are actually j2k files. These can be encoded by image_to_j2k from openjpeg. The script converts jpg-files to tga-files, which can then be used by image_to_j2k for j2k conversion. At the end the j2k file is renamed to jp2, and can be used as an secondlife texture. Please notice that all textures must have 32,64,128,256,512,1024,etc. dimensions. The script doesn't resize the images yet, but maybe it can be adopted to match the required dimensions...
+
{{Quicklinks}}
 +
<br />
  
==Usage==
+
== Description ==
* Install OpenJPEG svn (if you have trouble compiling, you could try the binaries on their site)
+
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.
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:
+
== Code ==
perl jp2batch.pl
+
<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
  
==Code==
+
$dirs=0;
#!/usr/bin/perl -s -U
+
$files=0;
# jp2batch.pl
+
 
# OpenSim jp2 texture preparation script
+
sub ScanDirectory{
# Converts jpg/jpeg/bmp/tga files to valid jp2(jk2) files for SL
+
  my ($workdir) = @_;
# Author: Phrearch
+
  local (@names);
# Credits: Tedd1
+
  $dirs++;
+
opendir(DIR, $workdir) or die "Unable to open $workdir:$!\n";
$dirs=0;
+
@names = readdir(DIR) or die "Unable to read $workdir:$!\n";
$files=0;
+
closedir(DIR);
+
foreach my $tmpName (@names){
sub ScanDirectory{
+
my $name = $workdir."/".$tmpName;
  my ($workdir) = @_;
+
#\. or \.. in directory
  local (@names);
+
if ($tmpName =~ /^\.\.?$/){
  $dirs++;
+
next;
opendir(DIR, $workdir) or die "Unable to open $workdir:$!\n";
+
}
@names = readdir(DIR) or die "Unable to read $workdir:$!\n";
+
#directory
closedir(DIR);
+
if (-d $name){
foreach my $tmpName (@names){
+
print "Entering directory $name\n";
my $name = $workdir."/".$tmpName;
+
&ScanDirectory($name);
#\. or \.. in directory
+
next;
if ($tmpName =~ /^\.\.?$/){
+
}
next;
+
#jpg or jpeg
}
+
if ($name =~ /^(.*)\.(jpe?g|bmp|tga|tif|raw)$/){
#directory
+
$rawname = $1;
if (-d $name){
+
$ext = lc($2);
print "Entering directory $name\n";
+
$files++;
&ScanDirectory($name);
+
print "\nProcessing $name...";
next;
+
&Convert($rawname,$ext);
}
+
}
#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;
+
+
 
   
 
   
 +
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 = &supportedAR($ar);
+
$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 = &supportedAR($ar);
+
$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${opt}Y! $rawname.$ext $rawname.$ext &>/dev/null");
+
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...";
+
print "\nCreating jp2 file...";
system("image_to_j2k -i $rawname.$ext -o $rawname.j2k -r 20,10,1 &>/dev/null");
+
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("mv $rawname.j2k $rawname.jp2 &>/dev/null");
system("rm $rawname.$ext &>/dev/null");
+
system("rm $rawname.$ext &>/dev/null");
print "Done\n";
+
print "Done\n";
}
+
}
+
 
sub supportedAR{
+
sub supportedAR{
my ($ar) = @_;
+
my ($ar) = @_;
my @arReference=(1.0,0.5,0.25,0.125,0.0625);
+
my @arReference=(1.0,0.5,0.25,0.125,0.0625);
my $arOptimal;
+
my $arOptimal;
my $arDivTemp=1.0;
+
my $arDivTemp=1.0;
my $arDiv;
+
my $arDiv;
#Get optimal aspect ratio
+
#Get optimal aspect ratio
foreach (@arReference){
+
foreach (@arReference){
$arDiv=abs($ar-$_);
+
$arDiv=abs($ar-$_);
if($arDiv < $arDivTemp) {
+
if($arDiv < $arDivTemp) {
$arDivTemp=$arDiv;
+
$arDivTemp=$arDiv;
$arOptimal=$_;
+
$arOptimal=$_;
}
+
}
}
+
}
return $arOptimal;
+
return $arOptimal;
}
+
}  
+
 
sub supportedXY{
+
sub supportedXY{
my ($res) = @_;
+
my ($res) = @_;
my @resReference=(64.0,128.0,256.0,512.0,1024.0,2048.0);
+
my @resReference=(64.0,128.0,256.0,512.0,1024.0);
my $resOptimal;
+
my $resOptimal;
my $resDivTemp=4096.0;
+
my $resDivTemp=4096.0;
my $resDiv;
+
my $resDiv;
#Get optimal axis resolution
+
#Get optimal axis resolution
foreach (@resReference){
+
foreach (@resReference){
  $resDiv=abs($res-$_);
+
$resDiv=abs($res-$_);
if($resDiv < $resDivTemp) {
+
if($resDiv < $resDivTemp) {
$resDivTemp=$resDiv;
+
$resDivTemp=$resDiv;
$resOptimal=$_;
+
$resOptimal=$_;
}
+
}
}
+
}
return $resOptimal;
+
return $resOptimal;
}  
+
}  
+
 
&ScanDirectory(".");
+
if ( @ARGV > 0 ){
print "\nDirectories scanned:$dirs\nFiles processed:$files\n" ;
+
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"
Personal tools
General
About This Wiki