Jp2 batch converter
From OpenSimulator
(Difference between revisions)
												
			 (→Code)  | 
			m (Robot: Replacing 'OpenSim' to 'OpenSimulator', which is the precise name)  | 
			||
| (12 intermediate revisions by 4 users not shown) | |||
| Line 1: | Line 1: | ||
| − | + | __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.  | |
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | ==Code==  | + | == Code ==  | 
| + | <source lang="perl">  | ||
#!/usr/bin/perl -s -U  | #!/usr/bin/perl -s -U  | ||
# jp2batch.pl  | # jp2batch.pl  | ||
| − | #   | + | # OpenSimulator jp2 texture preparation script  | 
# Converts jpg/jpeg/bmp/tga files to valid jp2(jk2) files for SL  | # Converts jpg/jpeg/bmp/tga files to valid jp2(jk2) files for SL  | ||
# Author: Phrearch  | # Author: Phrearch  | ||
| Line 27: | Line 18: | ||
$files=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){  | 	foreach my $tmpName (@names){  | ||
	my $name = $workdir."/".$tmpName;  | 	my $name = $workdir."/".$tmpName;  | ||
| Line 57: | Line 48: | ||
  }  |   }  | ||
| − | + | 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 =   | + | 	$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 =   | + | 	$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${  | + | 		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...";  | |
| − | + | 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"