两幅图像的融合与叠加

假设两幅图像的大小完全一致,对应的像素数组分别为A与B,对应的任意单个像素值分别是a与b,混合后的像素值为c
几种典型图像叠加操作:
1、乘法叠加
c=(ab)/255 public int modeOne(int v1,int v2){
return (v1
v2)/255;
}
2、加法叠加
c=(a+b)/2 public int modeTwo(int v1,int v2){
return (v1+v2)/2;
}
3、减法叠加
c=|a-b| public int modeThree(int v1,int v2){
return Math.abs(v1-v2);
}
4、取反叠加
c=255-((255-a)(255-b)/255)——首先对各自的像素取反,然后使用乘法叠加后对得到的结果再次取反。
public int modeFour(int v1,int v2){
double p = (int)((255-v1)
(255-v2));
return (int)(255-p/255);
}
5、加法取反叠加
c=255-(a+b) {(a+b)<255} | c=0 {(a+b)>=255}
public int modeFive(int v1,int v2){
int p = (int) (v1+v2);
if(p>255){
return 0;
}else{
return 255-p;
}

                           }

6、除法取反叠加
c=(a/(255-b))255 public int modeSix(int v1,int v2){
if(v2==255)
return 0;
double p = (v1/(255-v2))
255;
return clamp((int)p);
}
主要代码如下:
package chapter5;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

/**

  • Created by LENOVO on 18-1-30.
    */
    public class BlendFilter extends AbstractBufferedImageOp {
    public static final int MULTIPLY_PIXEL = 1;
    public static final int PLUS_PIXEL = 2;
    public static final int MINUS_PIXEL = 3;
    public static final int INVERSE_PIXEL = 4;
    public static final int INVERSE_PLUS_PIXEL = 5;
    public static final int DIVERSION_PIXEL = 6;

    private int mode;
    File file = new File("C:/Users/LENOVO/Desktop/rainbow.jpg");//读取的融合图片
    private BufferedImage secondImage ;
    public BlendFilter(){
    mode = MULTIPLY_PIXEL;//乘法叠加
    try {
    secondImage = ImageIO.read(file);

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

    }

    public void setMode(int mode) {
    this.mode = mode;
    }
    public void setSecondImage(BufferedImage secondImage) {
    this.secondImage = secondImage;
    }

    public BufferedImage filter(BufferedImage src,BufferedImage dest){
    checkImages(src);
    int width = src.getWidth();
    int height = src.getHeight();
    if(dest == null){
    dest = creatCompatibleDestImage(src,null);
    }
    int[] input1 = new int[widthheight];//原图
    int[] input2 = new int[secondImage.getWidth()
    secondImage.getHeight()];//第二张图
    int[] outPixels = new int[widthheight];
    getRGB(src,0,0,width,height,input1);
    getRGB(secondImage,0,0,secondImage.getWidth(),secondImage.getHeight(),input2);
    int index = 0;
    int ta1 = 0,tr1 = 0,tg1 = 0,tb1 = 0;
    for(int row=0;row<height;row++){
    for(int col=0;col<width;col++){
    index = row
    width +col;
    ta1 = (input1[index] >> 24) & 0xff;
    tr1 = (input1[index] >> 16) & 0xff;
    tg1 = (input1[index] >> 8) & 0xff;
    tb1 = (input1[index]) & 0xff;
    int rgb[] = getBlendData(tr1,tg1,tb1,input2,row,col);
    outPixels[index] = (ta1 << 24) | (clamp(rgb[0]) << 16) |(clamp(rgb[1]) << 8) |clamp(rgb[2]);
    }
    }
    setRGB(dest,0,0,width,height,outPixels);
    return dest;
    }

    //获取融合后的像素数据
    private int[] getBlendData(int tr1,int tg1,int tb1,int[] input,int row,int col){
    int width = secondImage.getWidth();
    int height = secondImage.getHeight();
    int index = row*width+col;
    if(col>=width || row >=height){//
    return new int[]{tr1,tg1,tb1};
    }
    int tr = (input[index] >> 16) & 0xff;
    int tg = (input[index] >>8) & 0xff;
    int tb = (input[index]) & 0xff;
    int[] rgb = new int[3];

     if(mode == MULTIPLY_PIXEL){
         rgb[0] = modeOne(tr1,tr);
         rgb[1] = modeOne(tg1,tg);
         rgb[2] = modeOne(tb1,tb);
     }else if(mode == PLUS_PIXEL){
         rgb[0] = modeTwo(tr1,tr);
         rgb[1] = modeTwo(tg1,tg);
         rgb[2] = modeTwo(tb1,tb);
     }else if(mode == MINUS_PIXEL){
         rgb[0] = modeThree(tr1,tr);
         rgb[1] = modeThree(tg1,tg);
         rgb[2] = modeThree(tb1,tb);
     }else if(mode == INVERSE_PIXEL){
         rgb[0] = modeFour(tr1,tr);
         rgb[1] = modeFour(tg1, tg);
         rgb[2] = modeFour(tb1, tb);
     }else if(mode == INVERSE_PLUS_PIXEL){
         rgb[0] = modeFive(tr1, tr);
         rgb[1] = modeFive(tg1, tg);
         rgb[2] = modeFive(tb1, tb);
     }else if(mode == DIVERSION_PIXEL){
         rgb[0] = modeSix(tr1, tr);
         rgb[1] = modeSix(tg1, tg);
         rgb[2] = modeSix(tb1, tb);
     }
     return rgb;
    

    }
    //乘法叠加
    public int modeOne(int v1,int v2){
    return (v1v2)/255;
    }
    //加法叠加
    public int modeTwo(int v1,int v2){
    return (v1+v2)/2;
    }
    //减法叠加
    public int modeThree(int v1,int v2){
    return Math.abs(v1-v2);
    }
    //取反叠加
    public int modeFour(int v1,int v2){
    double p = (int)((255-v1)
    (255-v2));
    return (int)(255-p/255);
    }
    //加法取反叠加
    public int modeFive(int v1,int v2){
    int p = (int) (v1+v2);
    if(p>255){
    return 0;
    }else{
    return 255-p;
    }
    }
    //除法取反叠加
    public int modeSix(int v1,int v2){
    if(v2 == 255)
    return 0;
    double p = (v1/(255-v2))*255;
    return clamp((int)p);
    }
    //判断两张图像大小是否相同
    public void checkImages(BufferedImage src){
    int width = src.getWidth();
    int height = src.getHeight();
    if(secondImage == null || secondImage.getWidth()>width || secondImage.getHeight()>height){
    throw new IllegalArgumentException("输入图片必须要大于融合的图片");
    }
    }
    }
    主要代码如下:

原文地址:https://www.cnblogs.com/bigdream6/p/8385886.html