Jp2 batch converter

From OpenSimulator

(Difference between revisions)
Jump to: navigation, search
(New page: #!/usr/bin/perl $iteration=1; foreach my $file(`ls *.jpg`) { chop($file); system("jasper --input $file --output $iteration.jp2 -T jp2;"); $iteration++; })
 
m (Robot: Replacing 'OpenSim' to 'OpenSimulator', which is the precise name)
 
(28 intermediate revisions by 4 users not shown)
Line 1: Line 1:
#!/usr/bin/perl
+
__NOTOC__
$iteration=1;
+
{{Quicklinks}}
 +
<br />
  
foreach my $file(`ls *.jpg`) {
+
== Description ==
chop($file);
+
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.
system("jasper --input $file --output $iteration.jp2 -T jp2;");
+
 
$iteration++;
+
== 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)
 +
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