How to convert a color image into sepia image

Image Processing Project

In this project we will learn to convert a color image into sepia image using Java programming language.

Prerequisite

It is assumed that you have completed the projects titled How to read and write image file in Java and How to get and set pixel value in Java before starting this project.

Color image to sepia image

Converting a color image into sepia image is very simple. All we have to do is repeat 3 simple steps for each pixels of the image.

  1. Get the RGB value of the pixel.
  2. Calculate tr, tg and tb using the formula

    tr = 0.393R + 0.769G + 0.189B
    tg = 0.349R + 0.686G + 0.168B
    tb = 0.272R + 0.534G + 0.131B

    Take the integer value.

  3. Set the new RGB value of the pixel as per the following condition:

    If tr > 255 then r = 255 else r = tr
    If tg > 255 then g = 255 else g = tg
    If tb > 255 then b = 255 else b = tb

Example:

Consider a color pixel with the following values

A = 255

R = 100

G = 150

B = 200

Where A, R, G and B represents the Alpha, Red, Green and Blue value of the pixel.

Remember! ARGB will have an integer value in the range 0 to 255.

So, to convert the color pixel into sepia pixel we have to first calculate tr, tg and tb.

tr = 0.393(100) + 0.769(150) + 0.189(200)

tr = 192.45

tr = 192 (taking integer value)

Similarly,

tg = 0.349(100) + 0.686(150) + 0.168(200) = 171 (taking integer value)

and tb = 0.272(100) + 0.534(150) + 0.131(200) = 133 (taking integer value)

Now we will replace the value of R, G and B with the new value that we calculated for the pixel.

So, the new pixel value will be

A = 255

R = 192

G = 171

B = 133

Note! We don't have to change the alpha value because it only controls the transparency of the pixel.

Import the required classes

Create a new file and save it by the name Sepia.java. Open the file and import the following:

import java.io.File;
import java.io.IOException;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;

Create the class

Next we will create the class by the name Sepia and inside the class we will have the main() method. For this we will write:

public class Sepia{
public static void main(String args[])throws IOException{

// some code goes here...

}//main() ends here
}//class ends here

Variables

Inside the main() method we create a BufferedImage variable img and a File variable f and set both of them to null. The img variable will hold the image file while the f variable will hold the image file path.

BufferedImage img = null;
File f = null;

Read the image file

For this project we will read the color image file zeenat.jpg and it is inside the Image folder which is inside D: drive on a Windows PC. So, we will first create an object of File class and pass as parameter the image file path. And then we will read the image file by calling the read() method of ImageIO class. So, our code will look something like the following:

//read image
try{
f = new File("D:\\Image\\zeenat.jpg");
img = ImageIO.read(f);
}catch(IOException e){
System.out.println(e);
}

Get image dimensions

Now that we have the image stored in the img variable, it's time for us to find the dimensions of the image. For this we will create two integer variable width and height and use the getWidth() andgetHeight() method to get the width and height of the image respectively. So, we will write the following lines.

//get image width and height
int width = img.getWidth();
int height = img.getHeight();

Sepia code

We know that an image is made up of pixels which we can represent in 2D co-ordinate. So, we will create two variables x and y and use two for loops to traverse each pixels. This part is simlar to How to convert a color image into grayscale image in Java.

For this we will write:

for(int y = 0; y < height; y++){
for(int x = 0; x < width; x++){

// some code goes here...

}
}

Get pixel value and extract ARGB value

Inside the for loop we will first get the value of the pixel at co-ordinate (x,y) using thegetRGB(x,y) method. Then we will extract the Alpha, Red, Green and Blue value from the pixel value. For this purpose we will create 5 integer variables p, a, r, g and b to hold the pixel, alpha, red, green and blue value respectively.

int p = img.getRGB(x,y);
int a = (p>>24)&0xff;
int r = (p>>16)&0xff;
int g = (p>>8)&0xff;
int b = p&0xff;

Calculate tr, tg and tb

Now, we will calculate the value of tr, tg and tb using the following formula:

tr = 0.393R + 0.769G + 0.189B
tg = 0.349R + 0.686G + 0.168B
tb = 0.272R + 0.534G + 0.131B

So, we will write

int tr = (int)(0.393*r + 0.769*g + 0.189*b);
int tg = (int)(0.349*r + 0.686*g + 0.168*b);
int tb = (int)(0.272*r + 0.534*g + 0.131*b);

Note! we are only interested with the integer value hence we have saved the average value in an integer variable.

Check condition and set pixel

Now, we will find the new value of r, g and b using the following condition:

If tr > 255 then r = 255 else r = tr
If tg > 255 then g = 255 else g = tg
If tb > 255 then b = 255 else b = tb

So, we will write the following code:

if(tr > 255){
r = 255;
}else{
r = tr;
}
if(tg > 255){
g = 255;
}else{
g = tg;
}
if(tb > 255){
b = 255;
}else{
b = tb;
}

We will now find the new pixel value and set it to the pixel at co-ordinate (x,y). For this we will write:

p = (a<<24) | (r<<16) | (g<<8) | b;
img.setRGB(x, y, p);

Write image

After the for loop ends we will write the image file. For this we will write the following code:

try{
f = new File("D:\\Image\\Output.jpg");
ImageIO.write(img, "jpg", f);
}catch(IOException e){
System.out.println(e);
}

Final code

/**
* File: Sepia.java
*
* Description:
* Convert color image to sepia image.
*
* @author Yusuf Shakeel
* Date: 27-01-2014 mon
*
* www.github.com/yusufshakeel/Java-Image-Processing-Project
*/
import java.io.File;
import java.io.IOException;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
public class Sepia{
public static void main(String args[])throws IOException{
BufferedImage img = null;
File f = null;

//read image
try{
f = new File("D:\\Image\\zeenat.jpg");
img = ImageIO.read(f);
}catch(IOException e){
System.out.println(e);
}

//get width and height of the image
int width = img.getWidth();
int height = img.getHeight();

//convert to sepia
for(int y = 0; y < height; y++){
for(int x = 0; x < width; x++){
int p = img.getRGB(x,y);

int a = (p>>24)&0xff;
int r = (p>>16)&0xff;
int g = (p>>8)&0xff;
int b = p&0xff;

//calculate tr, tg, tb
int tr = (int)(0.393*r + 0.769*g + 0.189*b);
int tg = (int)(0.349*r + 0.686*g + 0.168*b);
int tb = (int)(0.272*r + 0.534*g + 0.131*b);

//check condition
if(tr > 255){
r = 255;
}else{
r = tr;
}

if(tg > 255){
g = 255;
}else{
g = tg;
}

if(tb > 255){
b = 255;
}else{
b = tb;
}

//set new RGB value
p = (a<<24) | (r<<16) | (g<<8) | b;

img.setRGB(x, y, p);
}
}

//write image
try{
f = new File("D:\\Image\\Output.jpg");
ImageIO.write(img, "jpg", f);
}catch(IOException e){
System.out.println(e);
}
}//main() ends here
}//class ends here