Shader画笔填充
2015-11-12 15:50
639 查看
原图
先看一个例子
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>
再看一下IDE预览效果
看到图片周围水平,竖直方向的紫色和红色,绿色蓝色线条没,这就是使用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);
效果图
先看一个例子
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>
再看一下IDE预览效果
看到图片周围水平,竖直方向的紫色和红色,绿色蓝色线条没,这就是使用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);
效果图
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- android 代码实现控件之间的间距
- android FragmentPagerAdapter的“标准”配置
- Android"解决"onTouch和onClick的冲突问题
- android:installLocation简析
- android searchView的关闭事件
- SourceProvider.getJniDirectories