android 生成圆角和带倒影图片

 

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

}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值