图像处理------基于像素的图像混合-阿里云开发者社区

开发者社区> 人工智能> 正文
登录阅读全文

图像处理------基于像素的图像混合

简介: <p style="color: rgb(51, 51, 51); font-family: Arial; font-size: 14px; line-height: 26px;"><span style="font-size: 18px;">介绍几种常见的将两张图像混合在一起形成一张新的图像的算法,</span></p> <p style="color: rgb(51, 51, 51); f

介绍几种常见的将两张图像混合在一起形成一张新的图像的算法,

首先看一下下面算法演示中要使用的两张图像:



为了得到更好的混合效果,我选择了两张一样大小的图片。

方法一:

通过简单对于像素点的像素相乘得到输出像素值,代码演示如下:

[java] view plaincopy
  1. private int modeOne(int v1, int v2) {  
  2. <span style="white-space:pre">  </span>return (v1 * v2) / 255;  
  3. }  

方法一的效果如下:


方法二:

通过计算两个像素之和再减去方法一的输出值,代码如下:

[java] view plaincopy
  1. private int modeTwo(int v1, int v2) {  
  2.     return v1 + v2 - v1 * v2 / 255;  
  3. }  

方法二的效果如下:


方法三:

通过像素值128这个特殊的中值来求取输出值,代码如下:

[java] view plaincopy
  1. private int modeThree(int v1, int v2) {  
  2.     return (v2 < 128) ? (2 * v1 * v2 / 255):(255 - 2 * (255 - v1) * (255 - v2) / 255);  
  3. }  

方法三的效果如下:


方法四:

与方法三不同,中值127.5被用在计算等式中,代码如下:

[java] view plaincopy
  1. private int modeFour(double v1, double v2) {  
  2.   if ( v1 > 127.5 ){  
  3.       return (int)(v2 + (255.0 - v2) * ((v1 - 127.5) / 127.5) * (0.5 - Math.abs(v2-127.5)/255.0));  
  4.    }else{  
  5.       return (int)(v2 - v2 * ((127.5 -  v1) / 127.5) * (0.5 - Math.abs(v2-127.5)/255.0));  
  6.    }  
  7. }  

方法四的效果如下:


方法五:

中值计算考虑,是方法一的升级版本,使得混合更加精细,代码如下:

[java] view plaincopy
  1. private int modeFive(double v1, double v2) {  
  2.   if ( v1 > 127.5 ){  
  3.       return (int)(v2 + (255.0 - v2) * ((v1 - 127.5) / 127.5));  
  4.    }else{  
  5.       return (int)(v2 * v1 / 127.5);  
  6.    }  
  7. }  

方法五的效果如下:


滤镜源代码如下:

[java] view plaincopy
  1. package com.gloomyfish.filter.study;  
  2.   
  3. import java.awt.image.BufferedImage;  
  4. /*** 
  5.  * i get these blend method from html5 demo then i decide to  
  6.  * translate these java script methods into java 
  7.  * 偶尔我也会写中文注释, 常见的图像混合方法 
  8.  * @author fish 
  9.  * @date 2012-11-28 
  10.  */  
  11. public class ImageBlendFilter extends AbstractBufferedImageOp {  
  12.     /** Define the blend mode */  
  13.     public final static int MULTIPLY_PIXEL = 1;  
  14.     public final static int SCREEN_PIXEL = 2;  
  15.     public final static int OVERLAY_PIXEL = 3;  
  16.     public final static int SOFTLIGHT_PIXEL = 4;  
  17.     public final static int HARDLIGHT_PIXEL = 5;  
  18.       
  19.     private int mode;  
  20.     private BufferedImage secondImage;  
  21.     public ImageBlendFilter() {  
  22.         mode = 1;  
  23.     }  
  24.   
  25.     public void setBlendMode(int mode) {  
  26.         this.mode = mode;  
  27.     }  
  28.       
  29.     public void setSecondImage(BufferedImage image) {  
  30.         this.secondImage = image;  
  31.     }  
  32.       
  33.   
  34.     @Override  
  35.     public BufferedImage filter(BufferedImage src, BufferedImage dest) {  
  36.         checkImages(src);  
  37.         int width = src.getWidth();  
  38.         int height = src.getHeight();  
  39.   
  40.         if ( dest == null )  
  41.             dest = createCompatibleDestImage( src, null );  
  42.   
  43.         int[] input1 = new int[width*height];  
  44.         int[] input2 = new int[secondImage.getWidth() * secondImage.getHeight()];  
  45.         int[] outPixels = new int[width*height];  
  46.         getRGB( src, 00, width, height, input1);  
  47.         getRGB( secondImage, 00, secondImage.getWidth(), secondImage.getHeight(), input2);  
  48.         int index = 0;  
  49.         int ta1 = 0, tr1 = 0, tg1 = 0, tb1 = 0;  
  50.         for(int row=0; row<height; row++) {  
  51.             for(int col=0; col<width; col++) {  
  52.                 index = row * width + col;  
  53.                 ta1 = (input1[index] >> 24) & 0xff;  
  54.                 tr1 = (input1[index] >> 16) & 0xff;  
  55.                 tg1 = (input1[index] >> 8) & 0xff;  
  56.                 tb1 = input1[index] & 0xff;  
  57.                 int[] rgb = getBlendData(tr1, tg1, tb1, input2, row, col);  
  58.                 outPixels[index] = (ta1 << 24) | (rgb[0] << 16) | (rgb[1] << 8) | rgb[2];  
  59.                   
  60.             }  
  61.         }  
  62.         setRGB( dest, 00, width, height, outPixels );  
  63.         return dest;  
  64.     }  
  65.   
  66.     private int[] getBlendData(int tr1, int tg1, int tb1, int[] input,int row, int col) {  
  67.         int width = secondImage.getWidth();  
  68.         int height = secondImage.getHeight();  
  69.         if(col >= width || row >= height) {  
  70.             return new int[]{tr1, tg1, tb1};  
  71.         }  
  72.         int index = row * width + col;  
  73.         // int ta = (input[index] >> 24) & 0xff;  
  74.         int tr = (input[index] >> 16) & 0xff;  
  75.         int tg = (input[index] >> 8) & 0xff;  
  76.         int tb = input[index] & 0xff;  
  77.         int[] rgb = new int[3];  
  78.         if(mode == 1) {  
  79.             rgb[0] = modeOne(tr1, tr);  
  80.             rgb[1] = modeOne(tg1, tg);  
  81.             rgb[2] = modeOne(tb1, tb);  
  82.         }  
  83.         else if(mode == 2) {  
  84.             rgb[0] = modeTwo(tr1, tr);  
  85.             rgb[1] = modeTwo(tg1, tg);  
  86.             rgb[2] = modeTwo(tb1, tb);            
  87.         }  
  88.         else if(mode == 3) {  
  89.             rgb[0] = modeThree(tr1, tr);  
  90.             rgb[1] = modeThree(tg1, tg);  
  91.             rgb[2] = modeThree(tb1, tb);              
  92.         }  
  93.         else if(mode == 4) {  
  94.             rgb[0] = modeFour(tr1, tr);  
  95.             rgb[1] = modeFour(tg1, tg);  
  96.             rgb[2] = modeFour(tb1, tb);           
  97.         }  
  98.         else if(mode == 5) {  
  99.             rgb[0] = modeFive(tr1, tr);  
  100.             rgb[1] = modeFive(tg1, tg);  
  101.             rgb[2] = modeFive(tb1, tb);           
  102.         }  
  103.         return rgb;  
  104.     }  
  105.       
  106.     private int modeOne(int v1, int v2) {  
  107.         return (v1 * v2) / 255;  
  108.     }  
  109.       
  110.     private int modeTwo(int v1, int v2) {  
  111.         return v1 + v2 - v1 * v2 / 255;  
  112.     }  
  113.       
  114.     private int modeThree(int v1, int v2) {  
  115.         return (v2 < 128) ? (2 * v1 * v2 / 255):(255 - 2 * (255 - v1) * (255 - v2) / 255);  
  116.     }  
  117.       
  118.     private int modeFour(double v1, double v2) {  
  119.       if ( v1 > 127.5 ){  
  120.           return (int)(v2 + (255.0 - v2) * ((v1 - 127.5) / 127.5) * (0.5 - Math.abs(v2-127.5)/255.0));  
  121.        }else{  
  122.           return (int)(v2 - v2 * ((127.5 -  v1) / 127.5) * (0.5 - Math.abs(v2-127.5)/255.0));  
  123.        }  
  124.     }  
  125.       
  126.     private int modeFive(double v1, double v2) {  
  127.       if ( v1 > 127.5 ){  
  128.           return (int)(v2 + (255.0 - v2) * ((v1 - 127.5) / 127.5));  
  129.        }else{  
  130.           return (int)(v2 * v1 / 127.5);  
  131.        }  
  132.     }  
  133.   
  134.     private void checkImages(BufferedImage src) {  
  135.         int width = src.getWidth();  
  136.         int height = src.getHeight();  
  137.         if(secondImage == null || secondImage.getWidth() > width || secondImage.getHeight() > height) {  
  138.             throw new IllegalArgumentException("the width, height of the input image must be great than blend image");  
  139.         }  
  140.     }  
  141.   
  142. }  

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

分享: