Jul 26, 2007

Changing compression rate of JPEG image with Java

Sample code to change compression rate of JPEG file using Java.
Rasing compression rate until given rate.

import java.awt.*;
import java.awt.image.*;
import java.io.*;
import javax.swing.*;
import com.sun.image.codec.jpeg.*;
public class ProgressiveEncoder{

private static final long LN_MAX_FILE_SIZE_IN_BYTE = 65536L;

public static void main(String[] args){

String inFileName = "";
String outFileName = "out.jpg";
long maxFileSizeInByte = LN_MAX_FILE_SIZE_IN_BYTE;
float fqual = 1.0F;

if(args.length >= 3){
inFileName = args[0];
outFileName = args[1];
maxFileSizeInByte = Long.parseLong(args[2]);

}else if (args.length == 2){
inFileName = args[0];
outFileName = args[1];

}else if (args.length == 1){
inFileName = args[0];

}else{
throw new RuntimeException("Insufficient Parameters");
}


try{

Frame appFrame = new Frame("Compress");
ImageCanvas imgCanvas = new ImageCanvas();

Image img = new ImageIcon(inFileName).getImage();

imgCanvas.setImage(img);

appFrame.setSize(800,600);
appFrame.add(imgCanvas);
appFrame.setVisible(true);


BufferedImage bi = new BufferedImage(img.getWidth(imgCanvas),img.getHeight(imgCanvas),BufferedImage.TYPE_INT_RGB);
Graphics graph = bi.getGraphics();
graph.drawImage(img,0,0,imgCanvas);

JPEGEncodeParam encodeParam = JPEGCodec.getDefaultJPEGEncodeParam(bi);
OutputStream ostream = new FileOutputStream(outFileName);

for(fqual = 1.00F; fqual > 0.00F; fqual = fqual - 0.01F){

ByteArrayOutputStream baoutStream = new ByteArrayOutputStream();

encodeParam.setQuality(fqual,false);

JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder( baoutStream, encodeParam);
encoder.encode(bi);

if(baoutStream.size() <= maxFileSizeInByte){
ostream.write(baoutStream.toByteArray());
break;
}
}

ostream.flush();
ostream.close();
}catch(Exception ex){
ex.printStackTrace();
System.exit(9);
}

System.out.println("Quality=" + fqual);
System.exit(0);
}

}
class ImageCanvas extends Canvas{

private Image image_;

public ImageCanvas(){
super();

}

public void setImage(Image img){
image_ = img;
}

public void paint(Graphics g){
if(image_ != null){
g.drawImage(image_,0,0,this);
}
}

}

Resizing Images with Java

Sample code to resize image with Java.
Because I couldn't find proper ImageWriter GIF format changed to PNG.
When you use this on UNIX like Opearating Systems without X Window ,you need one of the followings

-Djava.awt.headless=true starting option
-PJA
-Xvfb

import java.awt.*;
import java.awt.image.*;
import java.io.*;
import javax.imageio.*;
import javax.imageio.stream.*;
public class Twinspark{
public static void main(String[] args){
if(args.length < 2){
System.out.println("Usage:");
System.out.println(" java Twinspark InputImageFile OutPutWidthInPixel");
System.exit(0);
}
String inputFileName = args[0];
int outputWidth = 0;
try{
outputWidth = Integer.parseInt(args[1]);
}catch(Throwable e){
System.out.println("OutPutWidthInPixel must be in Integer!");
e.printStackTrace();
System.exit(0);
}

if(outputWidth == 0){
System.out.println("OutPutWidthInPixel must be larger than 0!");
}

BufferedImage image = null;
try{
File inputFile = new File(inputFileName);
image = ImageIO.read(inputFile);
}catch(IOException e){
System.out.println("InputFile is not Found!");
e.printStackTrace();
System.exit(0);
}
String extension = inputFileName.substring(inputFileName.lastIndexOf(".") +1);
if(extension.toUpperCase().equals("GIF")){
extension = "png";
inputFileName = inputFileName.toLowerCase().replaceAll("\\.gif",".png");
}
Image outputImage = image.getScaledInstance(outputWidth,-1,Image.SCALE_SMOOTH);
BufferedImage bffImg = new BufferedImage(outputWidth,image.getHeight(null)* outputWidth /image.getWidth(null),BufferedImage.TYPE_3BYTE_BGR);
Graphics offg = bffImg.createGraphics();
offg.drawImage(outputImage, 0, 0, null);

try{
File outputFile = new File("after_" + inputFileName);
FileImageOutputStream fio = new FileImageOutputStream(outputFile);
ImageWriter iw = (ImageWriter) (ImageIO.getImageWritersBySuffix(extension)).next();

iw.setOutput(fio);
iw.write(bffImg);

}catch(Exception e){
e.printStackTrace();
}
}
}