前言

Bitmap在开发中是经常遇到的,因为他用到的地方有很多,比如Android的图片预览,自定义相机,自定义美颜相机,图片滤镜,图像算法。。。。,既然使用场景这么多,今天就先讲一下Android中常用的吧。
今天,我们来说说Bitmap相关的绘制以及颜色滤镜。看看我们是怎样虐狗的哈

看看虐狗前的图原图,是一只可爱的阿拉斯加。

Bitmap 绘制

Bitmap的绘制,主要有以下4个方法,其中2、3可以说是一样的。

  1. drawBitmap(Bitmap bitmap, float left, float top, Paint paint)
  2. drawBitmap(Bitmap bitmap, Rect src, RectF dst,Paint paint)
  3. drawBitmap(Bitmap bitmap, Rect src, Rect dst,Paint paint)
  4. drawBitmap(Bitmap bitmap, Matrix matrix, Paint paint)

好了,下面我们一一来讲解这几种方法。

  • 方式一: drawBitmap(Bitmap bitmap, float left, float top, Paint paint)
    代码如下:
package com.example.myapp.view;import android.content.Context;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.os.Build;import android.util.AttributeSet;import android.view.View;import androidx.annotation.Nullable;import androidx.annotation.RequiresApi;import com.example.myapp.R;public class DrawBitmap extends View {    //绘制的所需要的画笔    private Paint paint;    public DrawBitmap(Context context) {        super(context);        initAttributeSet();    }    public DrawBitmap(Context context, @Nullable AttributeSet attrs) {        super(context, attrs);        initAttributeSet();    }    public DrawBitmap(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        initAttributeSet();    }    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)    public DrawBitmap(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {        super(context, attrs, defStyleAttr, defStyleRes);        initAttributeSet();    }    //初始化参数    private void initAttributeSet(){        paint = new Paint();    }    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        paint.setColor(Color.RED); //画笔颜色        paint.setStrokeWidth(3);   //边宽        Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.pig);        //左上角的坐标left,top        canvas.drawBitmap(bitmap, 100, 100, paint);    }}

看一下最终效果图:

注意:

这里的left,top为开始绘制起点的左上角的坐标

  • 方式二和三:drawBitmap(Bitmap bitmap, Rect src, RectF dst,Paint paint)
    代码如下:
package com.example.myapp.view;import android.content.Context;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.Rect;import android.os.Build;import android.util.AttributeSet;import android.view.View;import androidx.annotation.Nullable;import androidx.annotation.RequiresApi;import com.example.myapp.R;public class DrawBitmap extends View {    private Paint paint;    public DrawBitmap(Context context) {        super(context);        initAttributeSet();    }    public DrawBitmap(Context context, @Nullable AttributeSet attrs) {        super(context, attrs);        initAttributeSet();    }    public DrawBitmap(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        initAttributeSet();    }    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)    public DrawBitmap(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {        super(context, attrs, defStyleAttr, defStyleRes);        initAttributeSet();    }    //初始化参数    private void initAttributeSet(){        paint = new Paint();    }    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        paint.setColor(Color.RED);        paint.setStrokeWidth(3);        Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.pig);        Rect rectF = new Rect(100, 300, 300, 100);        canvas.drawRect(rectF, paint);        canvas.drawBitmap(bitmap, null, rectF, paint);        Rect dst = new Rect(0, 0, 300, 300);        Rect src = new Rect(0, 0, bitmap.getWidth() / 2, bitmap.getHeight() / 2);        canvas.drawRect(src, paint);        //src 本次绘制的原区域 dst 本次绘制的目标区域        canvas.drawBitmap(bitmap, src, dst, paint);        canvas.drawBitmap(bitmap, 0, bitmap.getHeight() / 2, paint);    }}

好了,执行以下,再看看虐狗后的图片。

注意:

这里的src 为本次绘制的原区域,dst 本次绘制的目标区域,简单来说,就是把src 区域的图像绘制到dst区域

  • 方式四:drawBitmap(Bitmap bitmap, Matrix matrix, Paint paint)**
          Matrix matrix = new Matrix();        //        //缩放                matrix.setScale(0.5f, 0.5f);        //        //平移        //        matrix.setTranslate(100, 100);        //        //旋转        //        matrix.setRotate(30);        //        //倾斜        //        matrix.setSkew(0.5f, 0.5f);        //                canvas.drawBitmap(bitmap, matrix, paint);

效果图如下:

注意:

这里的matrix为矩阵,可以对图像进行一些简单的处理

这只是最简单的方式,下面我们讲讲如何用矩阵算法实现复杂的滤镜效果。

ColorFilter颜色滤镜

首先,对于色彩的存储,Bitmap类使用一个32位的数值来保存。红(R)、绿(G)、蓝(B)及透明度(A)各占8位,也就是所谓的RGBA,每一个色彩分量的取值范围是0-255。透明度为0表示完全透明,为255时,色彩完全可见。
Android中的颜色矩阵是一个 4x5 的数字矩阵,它用来对图片的色彩进行处理。

而处理是方式就涉及到了矩阵的乘法,具体方式如下图:

简单的代码如下:

R1 = aR + bG + cB + dA + e;G1 = fR + gG + hB + iA + j;B1 = kR + lG + mB + nA + o;A1 = pR + qG + rB + sA + t;

这也解释了为啥用五阶矩阵,比如说只是在原R上添加一些偏移量,使用四阶矩阵难以实现这个效果,(四阶矩阵只能实现乘法效果) 下面我们结合一些实例,再来深入了解下蓝色模式。

蓝色模式
蓝色模式就是去掉红色和绿色,代码如下:

        ColorMatrix colorMatrix = new ColorMatrix(new float[]{                0, 0, 0, 0, 0,                0, 0, 0, 0, 0,                0, 0, 1, 0, 0,                0, 0, 0, 1, 0,        });        paint.setColorFilter(new ColorMatrixColorFilter(colorMatrix));        canvas.drawBitmap(bitmap, 400, 0, paint);

好了,看一下效果图:

反相:

        //反相        ColorMatrix colorMatrix = new ColorMatrix(new float[]{                -1, 0, 0, 0, 255,                0, -1, 0, 0, 255,                0, 0, -1, 0, 255,                0, 0, 0, 1, 0,        });        paint.setColorFilter(new ColorMatrixColorFilter(colorMatrix));        canvas.drawBitmap(bitmap, 400, 0, paint);

效果图如下:

变亮:
变量就是同时对R、G、B、A同时增大。
代码如下:

 ColorMatrix light = new ColorMatrix(new float[]{                1.2f, 0, 0, 0, 0,                0, 1.2f, 0, 0, 0,                0, 0, 1.2f, 0, 0,                0, 0, 0, 1.2f, 0,        });        paint.setColorFilter(new ColorMatrixColorFilter(light));        canvas.drawBitmap(bitmap, 400, 0, paint);

效果图如下:

灰度/去色
只要把RGB的色彩信息设置成一样;即:R=G=B,那么图像就变成了灰色:

        //灰度        ColorMatrix grey1 = new ColorMatrix(new float[]{                0.33f, 0.59f, 0.11f, 0, 0,                0.33f, 0.59f, 0.11f, 0, 0,                0.33f, 0.59f, 0.11f, 0, 0,                0, 0, 0, 1, 0,        });        paint.setColorFilter(new ColorMatrixColorFilter(grey1));        canvas.drawBitmap(bitmap, 400, 0, paint);

效果图:

当然,灰度算法,还有更高高深的,下面介绍一下另外一种算法,0.213, 0.715, 0.072 这是谷歌给出的比例,跟人眼的色彩学有关系。

        //灰度2=====谷歌算法        ColorMatrix grey2 = new ColorMatrix(new float[]{                0.213f, 0.715f, 0.072f, 0, 0,                0.213f, 0.715f, 0.072f, 0, 0,                0.213f, 0.715f, 0.072f, 0, 0,                0, 0, 0, 1, 0,        });        paint.setColorFilter(new ColorMatrixColorFilter(grey2));        canvas.drawBitmap(bitmap, 200, 0, paint);在这里插入代码片

效果图如下:

红绿反色

 //红绿反色        ColorMatrix rtog = new ColorMatrix(new float[]{                0, 1, 0, 0, 0,                1, 0, 0, 0, 0,                0, 0, 1, 0, 0,                0, 0, 0, 1, 0,        });        paint.setColorFilter(new ColorMatrixColorFilter(rtog));

效果图如下:

是不是很神奇,红毛的阿拉斯加瞬间被你绿了哈。哈哈哈。。。。。。。。。

变旧

        //变旧        ColorMatrix old = new ColorMatrix(new float[]{                1 / 2f, 1 / 2f, 1 / 2f, 0, 0,                1 / 3f, 1 / 3f, 1 / 3f, 0, 0,                1 / 4f, 1 / 4f, 1 / 4f, 0, 0,                0, 0, 0, 1, 0        });        paint.setColorFilter(new ColorMatrixColorFilter(old));        canvas.drawBitmap(bitmap, 200, 0, paint);

效果图如下:

粉调

 //粉调        ColorMatrix pink = new ColorMatrix(new float[]{                0.8f, 0, 0, 0, 0,                0, 0.8f, 0, 0, 0,                0, 0.7f, 0.7f, 0, 0,                0, 0, 0, 0.8f, 0,        });        paint.setColorFilter(new ColorMatrixColorFilter(pink));        canvas.drawBitmap(bitmap, 200, 0, paint);

效果图如下:

好了,如果感觉对你有帮助,是否可以给个小红心啦。

更多相关文章

  1. 手把手教学, android 使用 SVG
  2. Android(安卓)自定义View实现打钩(签到)的动画
  3. android UI——2D绘图中应该注意的那些坑
  4. [译]Android(安卓)SDK中关于View绘制流程的概述
  5. Android性能优化之Debug GPU Overdraw
  6. Android中Matrix用法实例分析
  7. 当我们讨论流畅度的时候,我们究竟在说什么?
  8. 使用achartengine开发曲线图相关的Android应用程序(zhuan)
  9. [Android基础] VideoView

随机推荐

  1. 图片
  2. 设计模式,你相信吗,只用两个函数实现事务!
  3. Elasticsearch 三个使用场景
  4. 金融企业云管平台建设的若干第一手经验
  5. 用 Keepalived+HAProxy 实现高可用负载均
  6. tp6控制器里直接调用验证器
  7. 小白前端入门笔记(12),设置哑链接
  8. 基于Mininet的MAC地址学习实验
  9. OpenDaylight实现轮询策略的负载均衡服务
  10. 摸鱼就是通透?还有多少你没意识到的毒金句