首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 移动开发 > 移动开发 >

图片相交形式 setXfermode

2013-10-29 
图片相交模式setXfermode网上的资料图片倒影原文地址http://onewayonelife.iteye.com/blog/1169176MainAct

图片相交模式 setXfermode

网上的资料         图片倒影  原文地址http://onewayonelife.iteye.com/blog/1169176

MainActivity

Java代码  图片相交形式  setXfermode
  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.  *  图片相交形式  setXfermode
  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, 0, 0, null);  
  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(), 0x70ffffff, 0x00ffffff,  
  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.     }  

================================================================================================================================


原文地址http://lipeng88213.iteye.com/blog/1189452

setXfermode 


设置两张图片相交时的模式 

我们知道 在正常的情况下,在已有的图像上绘图将会在其上面添加一层新的形状。 如果新的Paint是完全不透明的,那么它将完全遮挡住下面的Paint; 

而setXfermode就可以来解决这个问题 


一般来说 用法是这样的 

Java代码  图片相交形式  setXfermode
  1. Canvas canvas = new Canvas(bitmap1);  
  2.   
  3. paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));  
  4.   
  5. canvas.drawBitmap(mask, 0f, 0f, paint);    

就是在图片bitmap1上面绘制图片mask时 处理两者相交时候显示的问题 

canvas原有的图片 可以理解为背景 就是dst 
新画上去的图片 可以理解为前景 就是src 


Mode的值 如下图 

图片相交形式  setXfermode 


一个遮罩层的具体例子  原文http://lonesane.iteye.com/blog/791267

图片相交形式  setXfermode

由于中间黄色部分是进度条区域,带有一定的弧度而不是规则的长方形。刚开始想偷懒用了很多办法来实现效果都不理想。后来想到使用遮罩层可以非常方便的实现这个功能。

可以通过修改Paint的Xfermode来实现遮罩的效果。Xfermode的功能非常强大,在API DEMO的Graphics中的最后一项有demo。看一下怎么实现我们的这个进度条吧。

 

 

首先用图片处理软件制作一个和中间黄色区域相同的图形,我们将在代码中设置它做为遮罩。


图片相交形式  setXfermode

View的draw方法

 

Java代码  图片相交形式  setXfermode
  1. public void draw(Canvas canvas) {  
  2.         //背景部分,也就是上面的图形  
  3.         Bitmap background = BitmapFactory.decodeResource(getResources(),  
  4.                 R.drawable.guage);  
  5.         //遮罩,就是提取来部分  
  6.         Bitmap mask = BitmapFactory.decodeResource(getResources(),  
  7.                 R.drawable.mask);  
  8.           
  9.         canvas.drawColor(Color.WHITE);  
  10.         canvas.drawBitmap(background, 0, 0, null);  
  11.         Paint paint = new Paint();  
  12.         paint.setFilterBitmap(false);  
  13.   
  14.         int x = 0;  
  15.         int y = 0;  
  16.   
  17.         // draw the src/dst example into our offscreen bitmap  
  18.         int sc = canvas.saveLayer(x, y, x + background.getWidth(), y + background.getHeight(), null,  
  19.                 Canvas.MATRIX_SAVE_FLAG | Canvas.CLIP_SAVE_FLAG  
  20.                         | Canvas.HAS_ALPHA_LAYER_SAVE_FLAG  
  21.                         | Canvas.FULL_COLOR_LAYER_SAVE_FLAG  
  22.                         | Canvas.CLIP_TO_LAYER_SAVE_FLAG);  
  23.         // canvas.drawBitmap(mDstB, 0, 0, paint);  
  24.         canvas.drawRect(0, 0, background.getWidth() / 2, background  
  25.                 .getHeight(), paint);  
  26.         paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));  
  27.         // canvas.drawBitmap(mSrcB, 0, 0, paint);  
  28.         canvas.drawBitmap(mask, 0f, 0f, paint);  
  29.         paint.setXfermode(null);  
  30.         canvas.restoreToCount(sc);  
  31.   
  32.     }  
 

 

只用控制绘制的矩形的长度就可以实现进度条的效果了。


图片相交形式  setXfermode        图片相交形式  setXfermode     图片相交形式  setXfermode

我做的效果是这样的,图片弄成圆的,效果如下

图片相交形式  setXfermode

主要代码

// 圆形头像
        cover_user_photo = (CircularImage) view
                .findViewById(R.id.cover_user_photo);
        
        String iconpath = getActivity().getApplicationContext().getFilesDir().getAbsolutePath()+ "/";
        iconpath += YqApp.mUserSettings.getString(PreferenceKey.USER_PIC, "");
        File mfile = new File(iconpath);
        Bitmap bm = null;
        if (mfile.exists()) {// 若该文件存在
            bm = BitmapFactory.decodeFile(iconpath);
        }
        Drawable drawab = null;
        if (null != bm) {
            drawab = new BitmapDrawable(createFramedPhoto(
                    getActivity().getWindowManager().getDefaultDisplay().getWidth()/2,
                    getActivity().getWindowManager().getDefaultDisplay().getHeight()/2, bm, 400));
        }

        if (null != drawab)
            cover_user_photo.setBackgroundDrawable(drawab);
        else
            cover_user_photo.setImageResource(R.drawable.face);

 private Bitmap createFramedPhoto(int x, int y, Bitmap image, float outerRadiusRat) {  
            Drawable imageDrawable = new BitmapDrawable(image);  
            Bitmap output = Bitmap.createBitmap(x, y, Bitmap.Config.ARGB_8888);  
            Canvas canvas = new Canvas(output);  
      
            RectF outerRect = new RectF(0, 0, x, y);  
      
            Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);  
            paint.setColor(Color.RED);  
            canvas.drawRoundRect(outerRect, outerRadiusRat, outerRadiusRat, paint);  
      
            paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));  
            imageDrawable.setBounds(0, 0, x, y);  
            canvas.saveLayer(outerRect, paint, Canvas.ALL_SAVE_FLAG);  
            imageDrawable.draw(canvas);  
            canvas.restore();  
      
            return output;  
        } 


热点排行