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();
}

@Override
protected 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");
}

@Override
public 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 倒影
  2. Android 设置全屏,画图,加载位图
  3. 一个Android实现图片的倒影效果的代码示例
  4. Android bitmap位图旋转
  5. 特效--------圆角 倒影
  6. 转:[Android]倒影效果的ImagView
  7. Android 官方文档:(一)动画和图像 —— 1.5 画布和画图
  8. Android中几种图像特效处理的小技巧,比如圆角,倒影,还有就是图片
  9. Android学习(18)Canvas_画布(绘图)

随机推荐

  1. Android(安卓)实现不同字体颜色的TextVie
  2. Android(安卓)之 发送短信
  3. android app 与电脑wifi通信
  4. [置顶] 基于Android2.3.5系统:Java JDK AD
  5. android 按两次返回键退出
  6. [置顶] 论坛
  7. android对话框弹出方式动画
  8. Android中OptionMenu的使用
  9. android 以httpclient方式把数据提交到服
  10. Android(安卓)图形用户界面 之 绘图(一)