原图
先看一个例子
package com.example.androidtest; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.PorterDuff.Mode; import android.graphics.PorterDuffXfermode; import android.graphics.Shader.TileMode; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.graphics.Bitmap.Config; import android.graphics.BitmapFactory; import android.graphics.BitmapShader; import android.util.AttributeSet; import android.widget.ImageView; public class CircleView2 extends ImageView { public CircleView2(Context context) { super(context); } public CircleView2(Context context, AttributeSet attrs) { super(context, attrs); } public CircleView2(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } /** * 布局预览时会调用该方法 */ @Override public void setImageDrawable(Drawable drawable) { //得到布局中资源图片的Bitmap Bitmap bmp=getBitmapFromDrawable(drawable); //创建5倍大小的Bitmap,用于在上面绘图 ,注意,一定要大于原始图片,否则看不到效果!把原图片铺在该图片上 Bitmap bitmap1=Bitmap.createBitmap(bmp.getWidth()*5,bmp.getHeight()*5,Config.ARGB_8888); /* * 创建Shader,第一个参数bmp相当于画笔的颜料,或者说是素材。 第二个参数是x方向如何显示,第三个参数是y方向如何显示 * * TileMode.CLAMP : 用边界像素填充(该例中把图片右侧边界像素水平拉伸,底部边界像素竖直拉伸) * * * TileMode.MIRROR : 镜像,即左右对称,上下对称 * * TileMode.REPEAT : 重复 */ BitmapShader shader=new BitmapShader(bmp, TileMode.CLAMP,TileMode.CLAMP); Paint paint=new Paint(); //为画笔添加“颜料” paint.setShader(shader); //避免边界毛边 paint.setAntiAlias(true); //在bitmap1 上画画, Canvas可以看做是手 Canvas canvas=new Canvas(bitmap1); // canvas.drawCircle(bitmap1.getWidth()/2 , bitmap1.getHeight()/2, bitmap1.getWidth()/2, paint); //用paint画笔画一个矩形,注意宽高是bitmap1的宽高!! canvas.drawRect(0,0,bitmap1.getWidth() , bitmap1.getHeight(), paint); super.setImageDrawable(new BitmapDrawable(bitmap1)); } // /** * 获取Drawable对应的Bitmap * @param drawable * @return */ private Bitmap getBitmapFromDrawable(Drawable drawable) { if (drawable == null) { return null; } if (drawable instanceof BitmapDrawable) { return ((BitmapDrawable) drawable).getBitmap(); } try { Bitmap bitmap; if (drawable instanceof ColorDrawable) { bitmap = Bitmap.createBitmap(1, 1, Config.ARGB_8888); } else { bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Config.ARGB_8888); } Canvas canvas = new Canvas(bitmap); drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight()); drawable.draw(canvas); return bitmap; } catch (OutOfMemoryError e) { return null; } } }
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#888" android:orientation="vertical" > <com.example.androidtest.CircleView2 android:layout_width="match_parent" android:layout_height="match_parent" android:background="#c00" android:src="@drawable/icc" /> </LinearLayout>
看到图片周围水平,竖直方向的紫色和红色,绿色蓝色线条没,这就是使用CLAMP填充的效果,图片的边界已经被拉伸了。
下面再看一下其他效果
BitmapShader shader=new BitmapShader(bmp, TileMode.REPEAT,TileMode.CLAMP);
横向重复,纵向镜像
BitmapShader shader=new BitmapShader(bmp, TileMode.REPEAT,TileMode.MIRROR);
横竖镜像
BitmapShader shader=new BitmapShader(bmp, TileMode.MIRROR,TileMode.MIRROR);
当然你也可以画出任意形状,比如画出圆形。 把上面代码中的 drawRect 换成 drawCircle 就可以了
canvas.drawCircle(bitmap1.getWidth()/2 , bitmap1.getHeight()/2, bitmap1.getWidth()/2, paint); //用paint画笔画一个矩形,注意宽高是bitmap1的宽高!! // canvas.drawRect(0,0,bitmap1.getWidth() , bitmap1.getHeight(), paint);
效果图