Jp2 batch converter

From OpenSimulator

(Difference between revisions)
Jump to: navigation, search
m (Usage)
m (Robot: Replacing 'OpenSim' to 'OpenSimulator', which is the precise name)
 
(16 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 checks for available tif-files in a root directory, and compresses those to j2k and renames them...
+
{{Quicklinks}}
 +
<br />
  
==Usage==
+
== 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
 +
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";
 +
}
 +
</source>
 +
 
 +
== 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 11: 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 directory where your jpg's 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 jpg2jp2.pl
+
  perl jp2batch.pl "/some directory/with/images"
 
+
 
+
==Code==
+
#!/usr/bin/perl -s -U
+
# jp2batch.pl by Phrearch
+
+
use Cwd;
+
$dirs=1;
+
$files=0;
+
+
sub ScanDirectory{
+
    my ($workdir) = shift;
+
 
+
    my ($startdir) = &cwd; # keep track of where we began
+
+
    chdir($workdir) or die "Unable to enter dir $workdir:$!\n";
+
    opendir(DIR, ".") or die "Unable to open $workdir:$!\n";
+
    my @names = readdir(DIR) or die "Unable to read $workdir:$!\n";
+
    closedir(DIR);
+
+
    foreach my $name (@names){
+
        next if ($name eq ".");
+
        next if ($name eq "..");
+
        if (-d $name){
+
        $dirs++;
+
        &ScanDirectory($name);
+
next;
+
        }
+
        if (substr($name, -4) eq ".jpg") {
+
print "Processing $workdir\\$name...";
+
$rawname = substr $name, 0, -4;
+
        system("convert -format tga $rawname.jpg $rawname.tga &>/dev/null");
+
system("rm $name &>/dev/null");
+
system("image_to_j2k -i $rawname.tga -o $rawname.j2k -r 20,10,1 &>/dev/null");
+
system("mv $rawname.j2k $rawname.jp2 &>/dev/null");
+
system("rm $rawname.tga &>/dev/null");
+
print "done!\n";
+
$files++;
+
        }
+
        chdir($startdir) or
+
          die "Unable to change to dir $startdir:$!\n";
+
    }
+
}
+
&ScanDirectory(".");
+
print "\nDirectories scanned:$dirs\nFiles processed:$files\n";
+

Latest revision as of 23: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