Tuesday 11 June 2013

Transparent Image Composition in Java :Fixing an Image over another with changing opacity or alpha of pixels

Hi all

I'm new to Blogger. And I'm starting with my first post regarding Image composition in java by applying varying transparency.

This is a funny program to fix one image over another with varying opacity levels. Its not using any built in methods in java for image composition or changing alpha value or pixels in images. By applying given opacity value over Red, Green and Blue values of each pixel from source image and fixing image a new RGB value can be obtained and set as pixel value of result image. A boundary range has given here, up to which the opacity value change from 0 to given value.

"flowers.jpg" is the source file on which the  "sachin.jpg" get fixed.

given  opacity = 0.5  , it can be between 0 and 1.

boundary = 120 , so 120 pixels from the side of image would have varying opacity from 0 to 0.5

The given image scaled to 420X488 pixel size and  it is inserted at  (350,100) of source image.



Here is my code....



public class ImageFixer {

    public static void main(String[] args) throws Exception {

        String dir = "C:\\Users\\Public\\Pictures\\Sample Pictures\\works\\";
        String src_file = "flowers.jpg";
        String fix_file = "sachin.jpg";
        String result_file = "result.jpg";
        int fix_pos_x = 350;  //position of fix image in source image
        int fix_pos_y = 100;
        int fix_img_width = 420; //new size for fix image
        int fix_img_height = 488;
        double opacity = .5; //alpha 0-1 of fix image
        double boundary = 120; //varying alpha boundary of fix image.

        BufferedImage source_img = ImageIO.read(new File(dir + src_file));
        BufferedImage fix_img = ImageIO.read(new File(dir + fix_file));
        ImageFixer imageFixer = new ImageFixer();

        BufferedImage result_img = imageFixer.compositeImage(
                source_img, fix_img, fix_pos_x, fix_pos_y, fix_img_width, fix_img_height, opacity, boundary);

        ImageIO.write(result_img, "JPEG", new File(dir + result_file));
    }

  public  BufferedImage compositeImage(
            BufferedImage source_img, BufferedImage fix_img,
            int fix_pos_x, int fix_pos_y,
            int fix_img_width, int fix_img_height,
            double opacity, double boundary) throws Exception {


        BufferedImage temp_img = new BufferedImage(fix_img_width, fix_img_height, fix_img.getType());
        temp_img.getGraphics().drawImage(fix_img, 0, 0, fix_img_width, fix_img_height, null);
        fix_img = temp_img;

        int w1 = source_img.getWidth();
        int w2 = fix_img.getWidth();
        int h1 = source_img.getHeight();
        int h2 = fix_img.getHeight();

        for (int x = fix_pos_x, x2 = 0; x < w1 && x2 < w2; x++, x2++) {
            for (int y = fix_pos_y, y2 = 0; y < h1 && y2 < h2; y++, y2++) {
                int[] rgbs2 = rgb(fix_img.getRGB(x2, y2));
                int[] rgbs1 = rgb(source_img.getRGB(x, y));
//calculate opacity for pixel (x2,y2) based on distance from given boundary
                double fx = opacity, fy = opacity;
                if (x2 <= boundary) {
                    fx = (x2 / boundary) * opacity;
                } else if (x2 >= w2 - boundary) {
                    fx = (w2 - x2) * opacity / boundary;
                }
                if (y2 <= boundary) {
                    fy = y2 * opacity / boundary;
                } else if (y2 >= h2 - boundary) {
                    fy = (h2 - y2) * opacity / boundary;
                }
                double _f = Math.min(fx, fy);
                double _g = 1.0 - _f;

                source_img.setRGB(x, y, rgb((int) (rgbs2[0] * _f + rgbs1[0] * _g),
                        (int) (rgbs2[1] * _f + rgbs1[1] * _g),
                        (int) (rgbs2[2] * _f + rgbs1[2] * _g)));
            }
        }

        return source_img;
    }

    int[] rgb(int rgb) {
        return new int[]{
            rgb >> 16 & 0xFF,
            rgb >> 8 & 0xFF,
            rgb & 0xFF
        };
    }

    int rgb(int r, int g, int b) {
        return (r << 16 | g << 8 | b);
    }
}




Results

flowers.jpg : Source Image to which another image get fixed

Base Image



 sachin.jpg : Fix Image, it would be inserted to the source image.


Image to Fix


sachinWithFlowers.jpg : Result image is the composite image, produced with given position, size, and opacity and boundary smoothness.

Result of Fixing

By making changes on the variables opacity, boundary and size values the result image could be different in look.