class BasicView2Draw extends View{Paint paint;Bitmap bitmap;public BasicView2Draw(Context context) {super(context);paint = new Paint(Paint.ANTI_ALIAS_FLAG);bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.icon);}private Bitmap createBitmap1(){Bitmap bitmap1 = Bitmap.createBitmap(100, 100, Config.ARGB_8888);Canvas canvas = new Canvas(bitmap1);canvas.drawColor(Color.BLUE);//  canvas.drawARGB(0, 0, 0, 0);// 透明色canvas.drawBitmap(bitmap, 0, 0, paint);canvas.drawText("Hello Android", 25, 55, paint);return bitmap1;}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);// 绘制位图// 1.绘制位图在(10,10)位置上canvas.drawBitmap(createBitmap1(), 10, 10, paint);// 2. canvas.drawBitmap(Bitmap bitmap,Rect src,Rect dest,Paint paint);// canvas.drawBitmap(Bitmap bitmap,Rect src,RectF dest,Paint paint);// 绘制位图到一个指定的矩形dest中,位图会自动进行平移和缩放等操作,如果src的参数不为null// 则会裁剪位图的部分区域来进行绘制Rect rect = new Rect(10, 10, 50, 60);RectF rectF1 = new RectF(180.0f, 20.0f, 240.0f, 80.0f);RectF rectF2 = new RectF(180.0f, 100.0f, 240.0f, 160.0f);canvas.drawBitmap(createBitmap1(), null, rectF1, paint);canvas.drawBitmap(createBitmap1(), rect, rectF2, paint);// 点paint.setStyle(Paint.Style.FILL_AND_STROKE);paint.setStrokeWidth(5.0f);paint.setColor(Color.YELLOW);canvas.drawPoints(new float[]{120,120,140,140,160,160,180,180}, paint);// 线paint.reset();// 重置画笔paint.setColor(Color.GREEN);paint.setAntiAlias(true);canvas.drawLine(30, 30, 130, 40, paint);paint.setColor(Color.RED);canvas.drawLines(new float[]{  40,40,140,40  ,50,50,90,90  }, paint);// 矩形paint.setColor(Color.CYAN);canvas.drawRect(10, 150, 150, 250, paint);paint.setColor(Color.GRAY);canvas.drawRect(new Rect(10, 260, 150, 280), paint);paint.setColor(Color.DKGRAY);canvas.drawRect(new RectF(20.2f, 290.9f, 120.2f, 300.3f), paint);// 绘制文本//paint.setTextSize(20);//paint.setColor(0x40ffffff);// 半透明白色//paint.setTextAlign(Paint.Align.RIGHT);// 对齐方向//canvas.drawText("Cool Android", 250, 180, paint);// 这里注意,坐标(180,180)是文本的左下点坐标// 画布平移:// 平移的单位是像素,分别是在x,y轴上平移的像素点// 正数代表的正方向,x轴为平面的右侧,y轴为平面的下方,相应的,负数则向反方向平移//canvas.translate(30.0f, 30.0f);// 画布缩放:// 参数分别是在想x,y轴上放大或缩小的倍数,大雨1为放大,小于1为缩小,// 缩放的原点默认为画布的原点(0,0),也可以指定缩放的原点//canvas.scale(2.0f, 1.5f);//canvas.scale(0.5f, 0.5f, 100.0f, 100.0f);// 指定坐标(100.0f,100.0f)为缩放原点// 这里剖析一下第二个缩放方法,其实系统为我们做的事情是这样的/*   scale(float sx, float sy, float px, float py){translate(px,py);scale(sx,sy);translate(-px,-py);}*/// 画布旋转// 1.以画布为原点,顺时针旋转40.0f度//canvas.rotate(40.0f);// 2.以(100.11f, 100.22f)为原点,顺时针旋转50.0f度//canvas.rotate(50.0f, 100.11f, 100.22f);// 相应的,为了加深理解,我们再剖析一下第二个旋转方法// ,其实系统为我们做的事情是这样的/*   rotate(float degrees, float px, float py){translate(px,py);rotate(degrees);translate(-px,-py);}*/// 画布倾斜// skew(float sx,float xy);将画布在x及y轴方向上倾斜相应的角度,sx或sy为倾斜角度的tan值,// 如canvas.skew(1,0);为在x方向上倾斜45度 >> tan(45) = 1//canvas.skew(1,0);}}

public class Matrix2Draw extends View {private Bitmap mBitmap;private Matrix mMatrix = new Matrix();public Matrix2Draw(Context context) {super(context);initialize();}private void initialize() {Bitmap bmp = ((BitmapDrawable)getResources().getDrawable(R.drawable.rotate_surfaceview)).getBitmap();mBitmap = bmp;/*首先,将缩放为100*100。这里scale的参数是比例。有一点要注意,如果直接用100/ bmp.getWidth()的话,会得到0,因为是整型相除,所以必须其中有一个是float型的, 直接用100f就好。*/mMatrix.setScale(100f/bmp.getWidth(), 100f/bmp.getHeight());/*// post 方式:后乘 >> 当前的矩阵乘以参数给出的矩阵。可以连续多次使用post,来完成所需的整个变换。 //平移到(100,100)处mMatrix.postTranslate(100, 100); //倾斜x和y轴,以(100,100)为中心。mMatrix.postSkew(0.2f, 0.2f, 100, 100);*/// pre 方式:前乘 >> 参数给出的矩阵乘以当前的矩阵。所以操作是在当前矩阵的最前面发生的。 //平移到(100,100)处mMatrix.preTranslate(100, 100); //倾斜x和y轴,以(100,100)为中心。mMatrix.preSkew(0.2f, 0.2f, 100, 100);}@Override protected void onDraw(Canvas canvas) {// super.onDraw(canvas); //如果界面上还有其他元素需要绘制,只需要将这句话写上就行了。Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);canvas.drawBitmap(mBitmap, mMatrix, paint);}}/** Matrix的操作: 总共分为translate(平移),rotate(旋转),scale(缩放)和skew(倾斜)四种,每一种变换在Android的API里都提供了set, post和pre三种操作方式,除了translate,其他三种操作都可以指定中心点。 set是直接设置Matrix的值,每次set一次,整个Matrix的数组都会变掉。 post是后乘,当前的矩阵乘以参数给出的矩阵。可以连续多次使用post,来完成所需的整个变换。 pre是前乘,参数给出的矩阵乘以当前的矩阵。所以操作是在当前矩阵的最前面发生的。 旋转、缩放和倾斜都可以围绕一个中心点来进行,如果不指定,默认情况下,是围绕(0,0)点来进行。 */


class BasicView2Draw extends View{Paint paint;Bitmap bitmap;public BasicView2Draw(Context context) {super(context);paint = new Paint(Paint.ANTI_ALIAS_FLAG);bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.icon);}private Bitmap createBitmap1(){Bitmap bitmap1 = Bitmap.createBitmap(100, 100, Config.ARGB_8888);Canvas canvas = new Canvas(bitmap1);canvas.drawColor(Color.BLUE);//  canvas.drawARGB(0, 0, 0, 0);// 透明色canvas.drawBitmap(bitmap, 0, 0, paint);canvas.drawText("Hello Android", 25, 55, paint);return bitmap1;}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);// 绘制位图// 1.绘制位图在(10,10)位置上canvas.drawBitmap(createBitmap1(), 10, 10, paint);// 2. canvas.drawBitmap(Bitmap bitmap,Rect src,Rect dest,Paint paint);// canvas.drawBitmap(Bitmap bitmap,Rect src,RectF dest,Paint paint);// 绘制位图到一个指定的矩形dest中,位图会自动进行平移和缩放等操作,如果src的参数不为null// 则会裁剪位图的部分区域来进行绘制Rect rect = new Rect(10, 10, 50, 60);RectF rectF1 = new RectF(180.0f, 20.0f, 240.0f, 80.0f);RectF rectF2 = new RectF(180.0f, 100.0f, 240.0f, 160.0f);canvas.drawBitmap(createBitmap1(), null, rectF1, paint);canvas.drawBitmap(createBitmap1(), rect, rectF2, paint);// 点paint.setStyle(Paint.Style.FILL_AND_STROKE);paint.setStrokeWidth(5.0f);paint.setColor(Color.YELLOW);canvas.drawPoints(new float[]{120,120,140,140,160,160,180,180}, paint);// 线paint.reset();// 重置画笔paint.setColor(Color.GREEN);paint.setAntiAlias(true);canvas.drawLine(30, 30, 130, 40, paint);paint.setColor(Color.RED);canvas.drawLines(new float[]{  40,40,140,40  ,50,50,90,90  }, paint);// 矩形paint.setColor(Color.CYAN);canvas.drawRect(10, 150, 150, 250, paint);paint.setColor(Color.GRAY);canvas.drawRect(new Rect(10, 260, 150, 280), paint);paint.setColor(Color.DKGRAY);canvas.drawRect(new RectF(20.2f, 290.9f, 120.2f, 300.3f), paint);// 绘制文本//paint.setTextSize(20);//paint.setColor(0x40ffffff);// 半透明白色//paint.setTextAlign(Paint.Align.RIGHT);// 对齐方向//canvas.drawText("Cool Android", 250, 180, paint);// 这里注意,坐标(180,180)是文本的左下点坐标// 画布平移:// 平移的单位是像素,分别是在x,y轴上平移的像素点// 正数代表的正方向,x轴为平面的右侧,y轴为平面的下方,相应的,负数则向反方向平移//canvas.translate(30.0f, 30.0f);// 画布缩放:// 参数分别是在想x,y轴上放大或缩小的倍数,大雨1为放大,小于1为缩小,// 缩放的原点默认为画布的原点(0,0),也可以指定缩放的原点//canvas.scale(2.0f, 1.5f);//canvas.scale(0.5f, 0.5f, 100.0f, 100.0f);// 指定坐标(100.0f,100.0f)为缩放原点// 这里剖析一下第二个缩放方法,其实系统为我们做的事情是这样的/*   scale(float sx, float sy, float px, float py){translate(px,py);scale(sx,sy);translate(-px,-py);}*/// 画布旋转// 1.以画布为原点,顺时针旋转40.0f度//canvas.rotate(40.0f);// 2.以(100.11f, 100.22f)为原点,顺时针旋转50.0f度//canvas.rotate(50.0f, 100.11f, 100.22f);// 相应的,为了加深理解,我们再剖析一下第二个旋转方法// ,其实系统为我们做的事情是这样的/*   rotate(float degrees, float px, float py){translate(px,py);rotate(degrees);translate(-px,-py);}*/// 画布倾斜// skew(float sx,float xy);将画布在x及y轴方向上倾斜相应的角度,sx或sy为倾斜角度的tan值,// 如canvas.skew(1,0);为在x方向上倾斜45度 >> tan(45) = 1//canvas.skew(1,0);}}


package com.view;import android.content.Context;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.Path;import android.graphics.Region;import android.util.AttributeSet;import android.view.View;/** *  ---------------------------------------------------矩形区域------------------------------------------------- *  canvas.clipRect(左上角x轴坐标, 左上角y轴坐标, 右下角x轴坐标, 右下角y轴坐标, Region.Op.XOR); *  最后一个参数有多个选择分别是: *  //DIFFERENCE是第一次不同于第二次的部分显示出来     //REPLACE是显示第二次的     //REVERSE_DIFFERENCE 是第二次不同于第一次的部分显示     //INTERSECT:交集显示     //UNION:全部显示     //XOR补集,就是全集的减去交集剩余部分显示     * @author emmet1988.iteye.com * */public class ClipRectDraw extends View {Context context;Paint paint;Path path;public ClipRectDraw(Context context) {super(context);init();}public ClipRectDraw(Context context, AttributeSet attrs) {super(context, attrs);init();}public ClipRectDraw(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);init();}private void init(){paint = new Paint();paint.setAntiAlias(true);paint.setStrokeWidth(5);paint.setTextSize(15);paint.setTextAlign(Paint.Align.RIGHT);path = new Path();}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);canvas.drawColor(Color.GRAY);//左上图canvas.save();canvas.translate(10, 10);drawScene(canvas);canvas.restore();//右上图canvas.save();canvas.translate(160, 10);canvas.clipRect(10, 10, 90, 90);canvas.clipRect(30, 30, 70, 70, Region.Op.XOR);drawScene(canvas);canvas.restore();//左中图canvas.save();canvas.translate(10, 130);path.reset();/*抛物曲线*/path.cubicTo(0, 0, 100, 0, 100, 100);path.cubicTo(100, 100, 0, 100, 0, 0);canvas.clipPath(path, Region.Op.REPLACE);drawScene(canvas);canvas.restore();//右中图canvas.save();        canvas.translate(160, 130);        canvas.clipRect(0, 0, 60, 60);        canvas.clipRect(40, 40, 100, 100, Region.Op.UNION);        drawScene(canvas);        canvas.restore();        //左下图        canvas.save();        canvas.translate(10, 250);        canvas.clipRect(0, 0, 60, 60);        canvas.clipRect(40, 40, 100, 100, Region.Op.XOR);        drawScene(canvas);        canvas.restore();        //右下图        canvas.translate(160, 250);        canvas.clipRect(0, 0, 60, 60);        canvas.clipRect(40, 40, 100, 100, Region.Op.REVERSE_DIFFERENCE);        drawScene(canvas);        canvas.restore();}private void drawScene(Canvas canvas){canvas.clipRect(0, 0, 100, 100);canvas.drawColor(Color.WHITE);paint.setColor(Color.RED);canvas.drawLine(0, 0, 100, 100, paint);paint.setColor(Color.GREEN);canvas.drawCircle(30, 70, 30, paint);paint.setColor(Color.BLUE);canvas.drawText("ChenJianLi", 100, 30, paint);}}


package com.view;import com.test.R;import android.content.Context;import android.graphics.Bitmap;import android.graphics.Canvas;import android.graphics.Matrix;import android.graphics.Paint;import android.graphics.drawable.BitmapDrawable;import android.view.View;/** * 在 Android 里面, Matrix 由 9 个 float 值构成,是一个 3*3 的矩阵。 * cosX, -sinX,translateX * sinX,  cosX,translateY * 0,0,scale * 解释一下,上面的 sinX 和 cosX ,表示旋转角度的 cos 值和 sin 值,注意, * 旋转角度是按顺时针方向计算的。 translateX 和 translateY 表示 x 和 y 的平移量。 * scale 是缩放的比例, 1 是不变, 2 是表示缩放 1/2 , * @author emmet1988.iteye.com * */public class MatrixDraw extends View implements Runnable{Bitmap bitmap;Matrix matrix = new Matrix();Paint paint;public MatrixDraw(Context context) {super(context);bitmap = ((BitmapDrawable)getResources().getDrawable(R.drawable.rotate_surfaceview)).getBitmap();paint = new Paint();paint.setAntiAlias(true);new Thread(this).start();}float m;float n;@Overrideprotected void onDraw(Canvas canvas) {/*float cosValue = (float)Math.cos(-Math.PI/m);float sinValue = (float)Math.sin(-Math.PI/m);Log.d("matrixdraw", "Math.PI =" + Math.PI);Log.d("matrixdraw", "Math.PI/m =" + Math.PI/m);Log.d("matrixdraw", "Math.cos(-Math.PI/m) =" + (float)Math.cos(-Math.PI/m));Log.d("matrixdraw", "Math.sin(-Math.PI/m) =" + (float)Math.sin(-Math.PI/m));matrix.setValues(new float[]{cosValue,-sinValue,100,sinValue,cosValue,100,0, 0, 2});//举例,若缩放值为0.9,代表放大原图的十分之一//super.onDraw(canvas);//当然,如果界面上还有其他元素需要绘制,只需要将这句话写上就行了。 //Matrix matrix2 = new Matrix(matrix);canvas.drawBitmap(bitmap, matrix, paint);//canvas.drawBitmap(bitmap, matrix2, paint);*/n ++;if (n == 60) {n = 0;}matrix.postRotate(n);matrix.postTranslate(n, n);matrix.postScale(1, 1, n, n);canvas.drawBitmap(bitmap, matrix, paint);}@Overridepublic void run() {while(!Thread.currentThread().isInterrupted()){try {Thread.sleep(100);postInvalidate();} catch (InterruptedException e) {Thread.currentThread().interrupt();}}}/** *  以左上角为顶点,缩放一半,逆时针旋转30度, *  然后沿x轴和y轴分别平移50个像素, *  代码 里面写的是100,为什么是平移50呢, *  因为缩放了一半。  *  大家可以自己设置一下Matrix的值,或者尝试一下两个 *  Matrix相乘,得到的值设置进去, *  这样才能对Matrix更加熟练。 */}


package com.view;import android.content.Context;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.Rect;import android.view.View;public class SimpleDraw extends View implements Runnable {/* * 我们继续来介绍Android平台底层绘图类的相关内容,在Android UI开发专题(一) * 之界面设计中我们介绍了有关Android平台资源使用以及Bitmap相关类的操作 * ,接下来将会以实例的方式给大家演示各种类的用处以及注意点。今天我们继续 * 了解android.graphics包中比较重要的绘图类。 *  * 一、 android.graphics.Matrix有关图形的变换、缩放等相关操作常用的方法有: * Java代码: void reset() // 重置一个matrix对象。 * void set(Matrix src) //复制一个源矩阵,和本类的构造方法 Matrix(Matrix src) 一样 * boolean isIdentity() //返回这个矩阵是否定义(已经有意义) * void setRotate(float degrees) //指定一个角度以0,0为坐标进行旋转 * void setRotate(float degrees, float px, float py) //指定一个角度以px,py为坐标进行旋转 *  void setScale(float sx, float sy) // 缩放 * void setScale(float sx, float sy, float px, float py) //以坐标px,py进行缩放 * void setTranslate(float dx, float dy) //平移 * void setSkew (float kx, float ky, float px, float py) //以坐标px,py进行倾斜 * void setSkew (float kx, float ky) //倾斜 复制代码 二、android.graphics.NinePatch *  * NinePatch是Android平台特有的一种非矢量图形自然拉伸处理方法,可以帮助常规的 * 图形在拉伸时不会缩放, * 实例中Android开发网提示大家对于Toast的显示就是该原理,同时SDK中提供了一 * 个工具名为Draw * 9-Patch,有关该工具的使用方法可以参考我们经发布的 Draw * 9-Patch使用方法介绍一文。由于该类提供了高质量支持透明的缩放方式,所以图形 * 格式为PNG,文件命名方式为.9.png * 的后缀比如eoeandroid。 *  * 三、android.graphics.Paint。Paint类我们可以理解为画笔、画刷的属性定义,本类 * 常用的方法如下: *  * Java代码: void reset() //重置 * void setARGB(int a, int r, int g, int b) 或 void setColor(int color) * //均为设置Paint对象的颜色 * void setAntiAlias(boolean aa) *  * //是否抗锯齿,需要配合void setFlags (Paint.ANTI_ALIAS_FLAG) 来帮助消除锯齿 * 使其边缘更平滑。 * Shader setShader(Shader shader) *  * //设置阴影,Shader类是一个矩阵对象,如果为NULL将清除阴影。 * void setStyle(Paint.Style style) //设置样式,一般为 FILL 填充,或者STROKE凹陷 * 效果。 * void setTextSize(float textSize) //设置字体大小 * void setTextAlign(Paint.Align align) //文本对齐方式 * Typeface setTypeface(Typeface typeface) * //设置字体,通过Typeface可以加载Android内部的字体,一般为宋体对于中文, * 部分ROM可以自己添加比如雅黑等等 * void setUnderlineText(boolean underlineText) *  * //是否设置下划线,需要撇和void setFlags (Paint.UNDERLINE_TEXT_FLAG) 方法。 复制代码 * 四、android.graphics.Rect *  * Rect我们可以理解为矩形区域,类似的还有Point一个点,Rect类除了表示一个矩 * 形区域位置描述外, * eoeandroid提示主要可以帮助我们计算图形之间是否碰撞 * (包含)关系,对于Android游戏开发比较有用,其主要的成员contains包含了三种 * 重载方法,来判断包含关系. *  * Java代码:  * boolean contains(int left, int top, int right, int bottom) * boolean contains(int x, int y) *  * boolean contains(Rect r) 复制代码 五、android.graphics.Region * Region在Android平台中表示一个区域和Rect不同的是 * ,它表示的是一个不规则的样子,可以是椭圆、多边形等等,而Rect仅仅是矩形。 * 同样Region的boolean contains(int x, * int y) 成员可以判断一个点是否在该区域内。 *  * 六、android.graphics.Typeface * Typeface类是帮助描述一个字体对象,在TextView中通过使用setTypeface方法来 * 制定一个输出文本的字体 * ,其直接构造调用成员create方法可以直接指定一个字体名称和样式,比如 * Java代码: static Typeface create(Typeface family, int style) *  * static Typeface create(String familyName, int style) 复制代码 * 同时使用isBold和isItalic方法可以判断出是否包含粗体或斜体的字型。 *  * Java代码: final boolean isBold() * final boolean isItalic() 复制代码 该类的创建方法还有从apk的资源或从一个具体的 * 文件路径,其具体方法为 * Java代码: static Typeface createFromAsset(AssetManager mgr, String path) * static Typeface createFromFile(File path) * static Typeface createFromFile(String path) 复制代码 */private Paint paint;public SimpleDraw(Context context) {super(context);paint = new Paint();new Thread(this).start();}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);canvas.drawColor(Color.GRAY);//paint.setAntiAlias(true);//canvas.save();//canvas.clipRect(10, 10, 110, 110);//canvas.drawColor(Color.WHITE);//// canvas.rotate(m);//以屏幕左上角为坐标原点旋转m += 45.0f;if (m == 360.0f) {m = 0.0f;}canvas.rotate(m, 60, 60);// 以(60,60)为原点旋转paint.setColor(Color.GREEN);canvas.drawRect(new Rect(50, 50, 70, 70), paint);canvas.restore();canvas.save();canvas.translate(140, 10);canvas.clipRect(0, 0, 100, 100);// 一定要先剪辑出矩形区域再设画布背景,//否则会覆盖整张画布canvas.drawColor(Color.BLACK);paint.setColor(Color.BLUE);canvas.drawRect(new Rect(10, 10, 50, 50), paint);canvas.restore();//canvas.save();canvas.translate(120, 120);canvas.clipRect(new Rect(0, 0, 100, 100));canvas.drawColor(Color.GREEN);// paint.setColor(Color.BLUE);paint.setStrokeWidth(4);paint.setColor(Color.BLACK);canvas.drawLine(0, 60, 100, 60, paint);paint.setARGB(255, 51, 51, 51);paint.setTextSize(20);paint.setFlags(Paint.ANTI_ALIAS_FLAG);paint.setUnderlineText(true);// paint.setFlags(Paint.UNDERLINE_TEXT_FLAG);canvas.drawText("陈建立", 25, 80, paint);paint.setColor(Color.WHITE);canvas.drawRect(new Rect(10, 10, 50, 50), paint);canvas.restore();}float m = 0.0f;public void run() {while (!Thread.currentThread().isInterrupted()) {try {Thread.sleep(500);// 每半秒执行一次} catch (InterruptedException e) {Thread.currentThread().interrupt();}postInvalidate();}}}
package com.view;import android.content.Context;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.Paint.FontMetrics;import android.util.Log;import android.view.View;public class TextDraw extends View {public TextDraw(Context context) {super(context);}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);Paint textPaint = new Paint( Paint.ANTI_ALIAS_FLAG);textPaint.setTextSize( 35);textPaint.setColor( Color.WHITE);// FontMetricsFontMetrics fontMetrics = textPaint.getFontMetrics();String text = "abcdefghijklm";// float baseX = 0;float baseY = 100;Log.d("textDraw", "top = "+fontMetrics.top+"ascent = "+fontMetrics.ascent+"descent = "+fontMetrics.descent+"bottom = "+fontMetrics.bottom+"\n");float topY = baseY + fontMetrics.top;float ascentY = baseY + fontMetrics.ascent;float descentY = baseY + fontMetrics.descent;float bottomY = baseY + fontMetrics.bottom;Log.d("textDraw", "topY = "+topY+"ascentY = "+ascentY+"descentY = "+descentY+"bottomY = "+bottomY);// canvas.drawText( text, baseX, baseY, textPaint);// BaseLinePaint baseLinePaint = new Paint( Paint.ANTI_ALIAS_FLAG);baseLinePaint.setColor( Color.RED);canvas.drawLine(0, baseY, getWidth(), baseY, baseLinePaint);// Basecanvas.drawCircle( baseX, baseY, 5, baseLinePaint);// TopLinePaint topLinePaint = new Paint( Paint.ANTI_ALIAS_FLAG);topLinePaint.setColor( Color.LTGRAY);canvas.drawLine(0, topY, getWidth(), topY, topLinePaint);// AscentLinePaint ascentLinePaint = new Paint( Paint.ANTI_ALIAS_FLAG);ascentLinePaint.setColor( Color.GREEN);canvas.drawLine(0, ascentY, getWidth(), ascentY, ascentLinePaint);// DescentLinePaint descentLinePaint = new Paint( Paint.ANTI_ALIAS_FLAG);descentLinePaint.setColor( Color.YELLOW);canvas.drawLine(0, descentY, getWidth(), descentY, descentLinePaint);// ButtomLinePaint bottomLinePaint = new Paint( Paint.ANTI_ALIAS_FLAG);bottomLinePaint.setColor( Color.MAGENTA);canvas.drawLine(0, bottomY, getWidth(), bottomY, bottomLinePaint);}}
class RoundImageView extends View {private Bitmap bitmap;int bitmapWidth;int bitmapHeight;public RoundImageView(Context context) {super(context);bitmap = BitmapFactory.decodeResource(getResources(),R.drawable.rotate_surfaceview);bitmapWidth = bitmap.getWidth();bitmapHeight = bitmap.getHeight();}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);// 第一种方法:/*Bitmap roundBitmap = Bitmap.createBitmap(bitmapWidth, bitmapHeight,Bitmap.Config.ARGB_8888);canvas = new Canvas(roundBitmap);Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);paint.setColor(Color.BLUE);canvas.drawRoundRect(new RectF(0, 0, bitmapWidth, bitmapHeight),20.0f, 20.0f, paint);paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));canvas.drawBitmap(bitmap, 0, 0, null);canvas.drawBitmap(roundBitmap, 0, 0, paint);*/// 第二种方法:Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);paint.setColor(0xffffffff);paint.setTextSize(15);canvas.drawText("生成带圆角的图片", 10, 25, paint);canvas.drawBitmap(getRoundedCornerBitmap(bitmap), 10, 30, paint);canvas.drawText("生成带倒影的图片", 170, 160, paint);canvas.drawBitmap(createReflectionImageWithOrigin(bitmap), 170, 165, paint);}public Bitmap getRoundedCornerBitmap(Bitmap bitmap) { // 创建一个指定宽度和高度的空位图对象  Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),bitmap.getHeight(), Config.ARGB_8888);  // 用该位图创建画布  Canvas canvas = new Canvas(output);  // 画笔对象  final Paint paint = new Paint();   // 画笔的颜色  final int color = 0xff424242;   // 矩形区域对象  final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());   // 未知  final RectF rectF = new RectF(rect);   // 拐角的半径  final float roundPx = 12;  // 消除锯齿  paint.setAntiAlias(true);   // 画布背景色  canvas.drawARGB(0, 0, 0, 0);  // 设置画笔颜色  paint.setColor(color);   // 绘制圆角矩形  canvas.drawRoundRect(rectF, roundPx, roundPx,paint);  // 未知  paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));  // 把该图片绘制在该圆角矩形区域中  canvas.drawBitmap(bitmap, rect, rect, paint);  // 最终在画布上呈现的就是该圆角矩形图片,然后我们返回该Bitmap对象return output; }//获得带倒影的图片方法 public Bitmap createReflectionImageWithOrigin(Bitmap bitmap){ // 图片与倒影之间的距离间隔final int reflectionGap = 2;// 原图的宽度int width = bitmap.getWidth(); // 原图的高度int height = bitmap.getHeight(); // 图片旋转,缩放等控制对象Matrix matrix = new Matrix(); // 缩放(这里pre,set,post三种效果是不一样的,注意区别)matrix.preScale(1, -1); /**  set是直接设置Matrix的值,每次set一次,整个Matrix的数组都会变掉。 post是后乘,当前的矩阵乘以参数给出的矩阵。可以连续多次使用post,来完成所需的整个变换。例如,要将一个图片旋转30度,然后平移到(100,100)的地方,那么可以这样做: Matrix m = new Matrix();m.postRotate(30);m.postTranslate(100, 100);  这样就达到了想要的效果。 pre是前乘,参数给出的矩阵乘以当前的矩阵。所以操作是在当前矩阵的最前面发生的。例如上面的例子,如果用pre的话,就要这样:Matrix m = new Matrix();m.setTranslate(100, 100);m.preRotate(30);旋转、缩放和倾斜都可以围绕一个中心点来进行,如果不指定,默认情况下,是围绕(0,0)点来进行。 关于缩放:scale的参数是比例。例如,我们缩放为100%,则有一点要注意,如果直接用100/bmp.getWidth()的话,会得到0,因为是整型相除,所以必须其中有一个是float型的,直接用100f就好 。如:matrix.setScale(100f/bmp.getWidth(), 100f/bmp.getHeight());    */// 创建一个初始的倒影位图Bitmap reflectionImage = Bitmap.createBitmap(bitmap, 0, height/2, width, height/2, matrix, false); // 新建一个宽度为原图宽度,高度为原图高度的3/2的位图,用于绘制新的位图,即整体的效果图位图对象Bitmap bitmapWithReflection = Bitmap.createBitmap(width, (height + height/2), Config.ARGB_8888); // 由该位图对象创建初始画布(规定了画布的宽高)Canvas canvas = new Canvas(bitmapWithReflection); // 在该画布上绘制原图canvas.drawBitmap(bitmap, 0, 0, null); // 创建一个画笔Paint deafalutPaint = new Paint(); // 绘制一个矩形区域,该矩形区域便是原图和倒影图之间的间隔图canvas.drawRect(0, height,width,height + reflectionGap,deafalutPaint); // 绘制该倒影图于间隔图的下方canvas.drawBitmap(reflectionImage, 0, height + reflectionGap, null); // 创建一个画笔Paint paint = new Paint();// 创建一个线性渐变对象LinearGradient shader = new LinearGradient(0, bitmap.getHeight(), 0, bitmapWithReflection.getHeight() + reflectionGap, 0x70ffffff, 0x00ffffff, TileMode.CLAMP  ); // 把渐变效果应用在画笔上paint.setShader(shader); // Set the Transfer mode to be porter duff and destination in // 未知paint.setXfermode(new PorterDuffXfermode(Mode.DST_IN)); // Draw a rectangle using the paint with our linear gradient // 绘制出该渐变效果,也就是最终的倒影效果图canvas.drawRect(0, height, width, bitmapWithReflection.getHeight() + reflectionGap, paint); // 返回return bitmapWithReflection; } }/** * 绘制圆角背景以及图片圆角的处理   .配置文件实现    <?xml version="1.0" encoding="utf-8"?>    <layer-list * xmlns:android="http://schemas.android.com/apk/res/android"> <item * android:drawable="@drawable/icon_home_button_img"/> <item * android:drawable="@drawable/icon_home_shape_overlay"/>  * </layer-list> * icon_home_shape_overlay如下  * <?xml version="1.0" encoding="utf-8"?>  * <shape * xmlns:android="http://schemas.android.com/apk/res/android"> <solid * android:color="#60000000"/>  * <stroke android:width="3dp" * color="#ff000000"/>  *<corners android:radius="10dp" />  * </shape> * 或者直接使用一种效果 * <?xml version="1.0" encoding="UTF-8"?>  * <shape * xmlns:android="http://schemas.android.com/apk/res/android">  * <solid * android:color="#99FFFFFF"/>  * <corners android:radius="30px"/> *<padding * android:left="0dp" android:top="0dp" android:right="0dp" * android:bottom="0dp" /> * </shape>  *  然后 * android:background="@drawable/my_shape_file" *  *  * 2.图片本身加上圆角 Bitmap myCoolBitmap = ... ; // <-- Your bitmap you want rounded  *  * int w = myCoolBitmap.getWidth(), h = myCoolBitmap.getHeight(); * Bitmap rounder = Bitmap.createBitmap(w,h,Bitmap.Config.ARGB_8888); Canvas * canvas = new Canvas(rounder); *  * Paint xferPaint = new Paint(Paint.ANTI_ALIAS_FLAG); * xferPaint.setColor(Color.RED); *  * canvas.drawRoundRect(new RectF(0,0,w,h), 20.0f, 20.0f, xferPaint); *  * xferPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN)); * canvas.drawBitmap(myCoolBitmap, 0,0, null);  * canvas.drawBitmap(rounder, 0,0, xferPaint);  * 或者  * public static Bitmap getRoundedCornerBitmap(Bitmap bitmap) {  * Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), * bitmap.getHeight(), Config.ARGB_8888);  * Canvas canvas = newCanvas(output); *  * final int color = 0xff424242; final Paint paint = new Paint(); final Rect *rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight()); final RectF * rectF = new RectF(rect); final float roundPx = 12; *  * paint.setAntiAlias(true); canvas.drawARGB(0, 0, 0, 0); * paint.setColor(color); canvas.drawRoundRect(rectF, roundPx, roundPx,paint); *  * paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN)); * canvas.drawBitmap(bitmap, rect, rect, paint); *  * return output;  * } */
package com.view;import com.test.R;import android.content.Context;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.Canvas;import android.graphics.Matrix;import android.graphics.Paint;import android.graphics.Rect;import android.util.Log;import android.view.SurfaceHolder;import android.view.SurfaceView;/** * http://wallage.blog.163.com/blog/static/173896242010101232220959/ * @author emmet1988.iteye.com * */public class SurfaceViewDraw extends SurfaceView implements Runnable,SurfaceHolder.Callback {private Bitmap backgroundBitmap;private Bitmap rotateBitmap;SurfaceHolder surfaceHolder;public SurfaceViewDraw(Context context) {super(context);backgroundBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.background_surfaceview);rotateBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.rotate_surfaceview);surfaceHolder = this.getHolder();surfaceHolder.addCallback(this);}public void surfaceCreated(SurfaceHolder holder) {new Thread(this).start();Log.d("surfaceview", "surfaceCreated");}public void surfaceChanged(SurfaceHolder holder, int format, int width,int height) {Log.d("surfaceview", "surfaceChanged");}public void surfaceDestroyed(SurfaceHolder holder) {Log.d("surfaceview", "surfaceDestroyed");}@Overridepublic void run() {Log.d("surfaceview", "run");Canvas canvas = null;int rotateValue = 0;//旋转角度int frameCount = 0;//帧计数器while (!Thread.currentThread().isInterrupted()) {try {    //canvas = surfaceHolder.lockCanvas();//获取画布对象(获取整个屏幕的画布)canvas = surfaceHolder.lockCanvas(new Rect(10, 10, 240, 250));//获取某个区域的画布Paint paint = new Paint();Log.d("surfaceview", "rotateValue " +rotateValue+"|frameCount "+frameCount);if (frameCount++ < 2) {//仅在第一次绘制时绘制背景/*  * 这里为什么设置成<2,而不是1,是由于SurfaceView本身的双缓冲技术。覆盖刷新其实就是将每次的新的图形绘制到上一帧去,所以如果图像是半透明的,就要考虑重复叠加导致的问题了,而如果是完全不透明的图形则不会有任何问题。背景会在背景图和黑色背景之间来回闪。这个问题其实是源于SurfaceView的双缓冲机制,我理解就是它会缓冲前两帧的图像交替传递给后面的帧用作覆盖,这样由于我们仅在第一帧绘制了背景,第二帧就是无背景状态了,且通过双缓冲机制一直保持下来,解决办法就是改为在前两帧都进行背景绘制。 */canvas.drawBitmap(backgroundBitmap, 0, 0, paint);//绘制背景}//创建矩阵以控制图片的旋转和平移Matrix matrix = new Matrix();rotateValue += 40;matrix.setRotate(rotateValue, rotateBitmap.getWidth()/2, rotateBitmap.getHeight()/2);//matrix.postRotate(rotateValue, rotateBitmap.getWidth()/2, rotateBitmap.getHeight()/2);//matrix.setTranslate(100, rotateValue);if (rotateValue == 360) {rotateValue = 0;  }matrix.setTranslate(80,50);//设置左边距和上边距//绘制问号Log.d("surfaceview", "canvas "+canvas);Log.d("surfaceview", "rotateBitmap "+rotateBitmap);Log.d("surfaceview", "matrix "+matrix);Log.d("surfaceview", "paint "+paint);if (canvas != null) {canvas.drawBitmap(rotateBitmap, matrix, paint);//解锁画布,提交画好的图像surfaceHolder.unlockCanvasAndPost(canvas);}Thread.sleep(30);} catch (InterruptedException e) {Thread.currentThread().interrupt();Log.d("surfaceview", "InterruptedException");} finally {Log.d("surfaceview", "finally");}}}}


   

更多相关文章

  1. Android实现对imageview的拖动以及缩放
  2. android:动态缩放和旋转图像
  3. Android中几种图像特效处理的小技巧,比如圆角,倒影,还有就是图片
  4. Android 图片缩放-Matrix
  5. Android学习(18)Canvas_画布(绘图)
  6. Android 利用ScaleDrawable实现缩放
  7. Android view手势缩放与移动
  8. 图片比例缩放以及bitMap转BitmapDrawable

随机推荐

  1. Android应用程序启动过程源代码分析(2)
  2. Android基本游戏循环实例分析
  3. 详解Android接口Interface的使用和意义
  4. Android NDK学习(5)调用.so文件
  5. Android okHttp上传单张或多张照片
  6. android适配器:ArrayAdapter
  7. android解决Unknown host 'jcenter.bintr
  8. android基础面试题(一)
  9. Android(安卓)视图(View)概述
  10. as报错