Android 图片倒影

Java代码   收藏代码
  1. package org.wp.activity;  
  2.   
  3. import android.app.Activity;  
  4. import android.graphics.Bitmap;  
  5. import android.graphics.Canvas;  
  6. import android.graphics.LinearGradient;  
  7. import android.graphics.Matrix;  
  8. import android.graphics.PorterDuffXfermode;  
  9. import android.graphics.Bitmap.Config;  
  10. import android.graphics.PorterDuff.Mode;  
  11. import android.graphics.Shader.TileMode;  
  12. import android.graphics.Paint;  
  13. import android.graphics.drawable.BitmapDrawable;  
  14. import android.os.Bundle;  
  15. import android.widget.ImageView;  
  16.   
  17. /** 
  18.  * ==========================================  
  19.  * Matrix 
  20.  * ==========================================  
  21.  * The Matrix class holds a 3x3 matrix for transforming coordinates.  
  22.  * Matrix does not have a constructor,  
  23.  * so it must be explicitly initialized using either reset()  
  24.  * - to construct an identity matrix,  
  25.  * or one of the set..() functions  
  26.  * (e.g. setTranslate, setRotate, etc.). 
  27.  *  
  28.  * Matrix 中文里叫矩阵,高等数学里有介绍 
  29.  * 在图像处理方面,主要是用于平面的缩放、平移、旋转等操作。 
  30.  * Matrix的操作,总共分为translate(平移),rotate(旋转), 
  31.  * scale(缩放)和skew(倾斜)四种, 
  32.  * 每一种变换在Android的API里都提供了set, post和pre三种操作方式 
  33.  * 除了translate,其他三种操作都可以指定中心点。  
  34.  *  
  35.  * ==========================================  
  36.  * createBitmap 
  37.  * ========================================== 
  38.  * public static Bitmap createBitmap (Bitmap source, int x, int y,  
  39.  *                  int width, int height, Matrix m, boolean filter)  
  40.  * Since: API Level 1 Returns an immutable bitmap from subset of the  
  41.  *        source bitmap, transformed by the optional matrix.  
  42.  *        It is initialized with the same density as the original bitmap. 
  43.  * Parameters 
  44.  * source  The bitmap we are subsetting  
  45.  * x  The x coordinate of the first pixel in source  
  46.  * y  The y coordinate of the first pixel in source  
  47.  * width  The number of pixels in each row  
  48.  * height  The number of rows  
  49.  * m  Optional matrix to be applied to the pixels  
  50.  * filter  true if the source should be filtered.  
  51.  *         Only applies if the matrix contains more than  
  52.  *         just translation.  
  53.  * Returns 
  54.  * A bitmap that represents the specified subset of source 
  55.  * Throws 
  56.  * IllegalArgumentException   
  57.  * if the x, y, width, height values are outside of the  
  58.  * dimensions of the source bitmap.  
  59.  *  
  60.  * source 源 bitmap对象 
  61.  * x 源坐标x位置 
  62.  * y 源坐标y位置 
  63.  * width 宽度 
  64.  * height 高度 
  65.  * m 接受的maxtrix对象,如果没有可以设置 为null 
  66.  * filter 该参数仅对maxtrix包含了超过一个翻转才有效 
  67.  *  
  68.  * ========================================== 
  69.  * LinearGradient 
  70.  * ========================================== 
  71.  * public LinearGradient (float x0, float y0, float x1, float y1, i 
  72.  *              nt color0, int color1, Shader.TileMode tile)  
  73.  * Since: API Level 1 Create a shader that draws a linear gradient along a line. 
  74.  * Parameters 
  75.  * x0  The x-coordinate for the start of the gradient line  
  76.  * y0  The y-coordinate for the start of the gradient line  
  77.  * x1  The x-coordinate for the end of the gradient line  
  78.  * y1  The y-coordinate for the end of the gradient line  
  79.  * color0  The color at the start of the gradient line.  
  80.  * color1  The color at the end of the gradient line.  
  81.  * tile  The Shader tiling mode   
  82.  *  
  83.  * 在android.graphics中我们可以找到有关Gradient字样的类, 
  84.  * 比如LinearGradient 线性渐变、RadialGradient径向渐变  和 角度渐变SweepGradient 三种, 
  85.  * 他们的基类为android.graphics.Shader。 
  86.  *  
  87.  * LinearGradient线性渐变 
  88.  * 在android平台中提供了两种重载方式来实例化该类分别为, 
  89.  * 他们的不同之处为参数中第一种方法可以用颜色数组,和位置来实现更细腻的过渡效果, 
  90.  * 比如颜色采样int[] colors数组中存放20种颜色,则渐变将会逐一处理。 
  91.  * 而第二种方法参数仅为起初颜色color0和最终颜色color1。 
  92.  * LinearGradient(float x0, float y0, float x1, float y1,  
  93.  *      int[] colors, float[] positions, Shader.TileMode tile)  
  94.  * LinearGradient(float x0, float y0, float x1, float y1,  
  95.  *      int color0, int color1, Shader.TileMode tile)  
  96.  *  
  97.  * 参数一为渐变起初点坐标x位置,参数二为y轴位置, 
  98.  * 参数三和四分辨对应渐变终点,最后参数为平铺方式,这里设置为镜像 
  99.  *  
  100.  * 刚才已经讲到Gradient是基于Shader类, 
  101.  * 所以我们通过Paint的setShader方法来设置这个渐变 
  102.  * p.setShader(lg); 
  103.  *  
  104.  * ========================================== 
  105.  * setXfermode 
  106.  * ========================================== 
  107.  * Xfermode 
  108.  * 可以通过修改Paint的Xfermode来影响在 
  109.  * Canvas已有的图像上面绘制新的颜色的方式 。 
  110.  *  
  111.  * 在正常的情况下,在已有的图像上绘图将会在其上面添加一层新的形状。 
  112.  * 如果新的Paint是完全不透明的,那么它将完全遮挡住下面的Paint; 
  113.  * 如果它是部分透明的,那么它将会被染上下面的颜色。 
  114.  *  
  115.  * 下面的Xfermode子类可以改变这种行为: 
  116.  *  
  117.  * AvoidXfermode  指定了一个颜色和容差, 
  118.  *                    强制Paint避免在它上面绘图(或者只在它上面绘图)。 
  119.  * PixelXorXfermode  当覆盖已有的颜色时,应用一个简单的像素XOR操作。 
  120.  *  
  121.  * PorterDuffXfermode  这是一个非常强大的转换模式,使用它, 
  122.  *                     可以使用图像合成的16条Porter-Duff规则的任意 
  123.  *                     一条来控制Paint如何与已有的Canvas图像进行交互。 
  124.  *  
  125.  * 16条Porter-Duff规则 
  126.  * 1.PorterDuff.Mode.CLEAR 
  127.  * 2.PorterDuff.Mode.SRC 
  128.  * 3.PorterDuff.Mode.DST 
  129.  * 4.PorterDuff.Mode.SRC_OVER 
  130.  * 5.PorterDuff.Mode.DST_OVER 
  131.  * 6.PorterDuff.Mode.SRC_IN 
  132.  * 7.PorterDuff.Mode.DST_IN 
  133.  * 8.PorterDuff.Mode.SRC_OUT 
  134.  * 9.PorterDuff.Mode.DST_OUT 
  135.  * 10.PorterDuff.Mode.SRC_ATOP 
  136.  * 11.PorterDuff.Mode.DST_ATOP 
  137.  * 12.PorterDuff.Mode.XOR 
  138.  * 13.PorterDuff.Mode.DARKEN 
  139.  * 14.PorterDuff.Mode.LIGHTEN 
  140.  * 15.PorterDuff.Mode.MULTIPLY 
  141.  * 16.PorterDuff.Mode.SCREEN  
  142.  *  
  143.  * @author wp 
  144.  */  
  145. public class MainActivity extends Activity {  
  146.   
  147.     @Override  
  148.     public void onCreate(Bundle savedInstanceState) {  
  149.         super.onCreate(savedInstanceState);  
  150.         setContentView(R.layout.main);  
  151.   
  152.         ImageView myImageView = (ImageView) this.findViewById(R.id.myImageView);  
  153.         Bitmap bitmap = ((BitmapDrawable) getResources().getDrawable(  
  154.                 R.drawable.qianqian)).getBitmap();  
  155.         myImageView.setImageBitmap(createReflectedImage(bitmap));  
  156.     }  
  157.   
  158.     private Bitmap createReflectedImage(Bitmap originalBitmap) {  
  159.         // 图片与倒影间隔距离  
  160.         final int reflectionGap = 4;  
  161.           
  162.         // 图片的宽度  
  163.         int width = originalBitmap.getWidth();  
  164.         // 图片的高度  
  165.         int height = originalBitmap.getHeight();  
  166.           
  167.         Matrix matrix = new Matrix();  
  168.         // 图片缩放,x轴变为原来的1倍,y轴为-1倍,实现图片的反转  
  169.         matrix.preScale(1, -1);  
  170.         // 创建反转后的图片Bitmap对象,图片高是原图的一半。  
  171.         Bitmap reflectionBitmap = Bitmap.createBitmap(originalBitmap, 0,  
  172.                 height / 2, width, height / 2, matrix, false);  
  173.         // 创建标准的Bitmap对象,宽和原图一致,高是原图的1.5倍。  
  174.         Bitmap withReflectionBitmap = Bitmap.createBitmap(width, (height  
  175.                 + height / 2 + reflectionGap), Config.ARGB_8888);  
  176.   
  177.         // 构造函数传入Bitmap对象,为了在图片上画图  
  178.         Canvas canvas = new Canvas(withReflectionBitmap);  
  179.         // 画原始图片  
  180.         canvas.drawBitmap(originalBitmap, 00null);  
  181.   
  182.         // 画间隔矩形  
  183.         Paint defaultPaint = new Paint();  
  184.         canvas.drawRect(0, height, width, height + reflectionGap, defaultPaint);  
  185.   
  186.         // 画倒影图片  
  187.         canvas.drawBitmap(reflectionBitmap, 0, height + reflectionGap, null);  
  188.   
  189.         // 实现倒影效果  
  190.         Paint paint = new Paint();  
  191.         LinearGradient shader = new LinearGradient(0, originalBitmap.getHeight(),   
  192.                 0, withReflectionBitmap.getHeight(), 0x70ffffff0x00ffffff,  
  193.                 TileMode.MIRROR);  
  194.         paint.setShader(shader);  
  195.         paint.setXfermode(new PorterDuffXfermode(Mode.DST_IN));  
  196.   
  197.         // 覆盖效果  
  198.         canvas.drawRect(0, height, width, withReflectionBitmap.getHeight(), paint);  
  199.   
  200.         return withReflectionBitmap;  
  201.     }  

你可能感兴趣的:(倒影,Matrix,图像处理,图像合成)