对于Canvas和Bitmap的一点认识

在Android关于Canvas的API描述中,一开始就如下描述:

To draw something, you need 4 basic components: A Bitmap to hold the pixels, a Canvas to host the draw calls (writing into the bitmap),

a drawing primitive (e.g. Rect, Path, text, Bitmap), and a paint (to describe the colors and styles for the drawing).

先翻译一下这句话,

想画一些东西的时候,你需要4个基本的组件,一个Bitmap来存储像素,一个Canvas来接收draw的调用(draw的结果是将像素给画到前面所讲的Bitmap中),

一个源,即是你想画的东西(比如矩形,路径,文本,抑或另一个位图),最后就是一个画笔(描述想画的颜色和风格等)

无意中看到这描述,我对Canvas和Bitmap的理解突然间有种原来就是这么简单的感觉。

Bitmap

首先想像一下,我们在屏幕上看到的图像,都是由一个一个的像素组成的,那么这些像素是从哪来的?由上面这句话,我们就知道答案了,这些像素就是存放在

Bitmap中的,由此,我们可以认为Bitmap就是用来直接展示在窗口上的一个显示对象,它是一个最终的产品。

我们知道,通过BitmapFactory,我们可以从资源(Resource),InputStream和文件中创建出一个Bitmap,并将其交给控件使用。

    public static Bitmap readBitmapFromResource(Context context, int resId) {
        BitmapFactory.Options op = new BitmapFactory.Options();
        op.inPreferredConfig = Bitmap.Config.ARGB_8888;
        op.inDither = false;
        op.inScaled = false;

        InputStream is = context.getResources().openRawResource(resId);
        return BitmapFactory.decodeStream(is, null, op);
    }

Canvas

那么怎么理解Canvas呢?

    Bitmap bitmap = Bitmap.createBitmap(width, height, Config.ARGB_8888);
    Canvas canvas = new Canvas(bitmap);

上面是创建Canvas的一段代码,由这,我们知道,要创建Canvas,必须先创建一个Bitmap对象,并将其作为参数传给Canvas。

那么,我们可以只创建Canvas,然后不给其传递Bitmap对象吗?

不可以!

为什么?

Canvas 本意是画布的意思,但是在Android中,它就只是一个媒介,可以通过Canvas来调用drawRect,drawCircle等等,但是实际上画的这些东西最终展现的时候,

都是像素,但是只有Bitmap才能保存像素,而Canvas并不行,所以在创建Canvas的时候,就必须传递一个Bitmap,用来承载画的内容。

可以这么理解,现在在我们面前有一张空白的纸(Bitmap),但是我们不能将画笔直接点到上面,我们必须先在这张纸上面放一块画布(Canvas),然后我们在这张画布上

开始点点点…最后,我们就可以看到,我们所有的形为都通过画布作用到纸上了,这时候,那张空白的纸已经是一张画了,而我们掀掉画布,就能够直接将这张画给别人看了。

而此时,Canvas已经没有作用了,它的作用只在于承接我们的画笔操作,然后将所对应位置的像素存储到对应的Bitmap中。

    canvas.drawPath(mPath, mHighlightPaint);
    return bitmap;

不知道,这么说,大家能够理解Canvas和Bitmap的关系不?

简单地说,我们要进行画画的操作,我们需要通过Canvas来实现,但是每一个Canvas都必须有相对应的Bitmap来承载内容,我们在Canvas上所作的操作最终都是会写到Bitmap中的。

而最终展现给用户看的内容,也是通过Bitmap来展现的。

上面还讲到两个东西,一个drawing primitive,一个paint,就比较好理解了,就不在这里多说了。

Drawable

而我们经常还会遇到一个Drawable的类,那这个东西又是什么呢,跟Bitmap又有什么关系呢?

A Drawable is a general abstraction for “something that can be drawn.”

Drawable就是能够被画到画布上的对象。

所以,Bitmap是一种Drawable,于是有了BitmapDrawable,颜色是一种Drawable,所以有了ColorDrawable. 形状是一种Drawable,所以有了ShapeDrawable。

个人觉得,它就是一个类似接口之类的东西,而本质上它也是一个抽象类,继承了Drawable,就表明这东东是可绘制的。

时间: 2024-10-13 14:47:36

对于Canvas和Bitmap的一点认识的相关文章

Android:使用Canvas合并Bitmap

关键点 canvas.drawBitmap(bitmap, srcRect, dstRect, null); 将bitmap的srcRect区域绘制到canvas的dstRect区域 Demo main.xml <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android&qu

利用canvas和bitmap如何对图片缩放到适应屏幕大小?

创建你自己想要大小的 bitmap public static Bitmap resizeBitmap(Bitmap bitmap, int w, int h) {        if (bitmap != null) {            int width = bitmap.getWidth();            int height = bitmap.getHeight();            int newWidth = w;            int newHeigh

用户注册问题的一点深度思考

朋友要做Web版的会员管理系统,请我帮忙谈谈用户注册的问题,我就斗胆畅谈了一些,尽我所能,尽我所知.本着技术分享的理念,特刊此文. 1.防止重复注册,需要先查找用户名是否存在,防止用户恶意注册,造成数据库冗余,性能受到影响: 2.防止软件注册机自动注册,需要加入图形验证码: 12306网站,用户注册/购买铁路票,开始没有图形验证码,导致众多刷票软件可以轻松抢票: 3.用户注册的时候,提交用户名和密码的时候,需要用POST方法,而不是GET方法,防止密码外泄,保证安全性: 4.MySQL数据库中,

Camera图片特效处理综述(Bitmap的Pixels处理、Canvas/paint的drawBitmap处理、旋转图片、裁截图片、播放幻灯片浏览图片&lt;线程固定时间显示一张&gt;)

一种是直接对Bitmap的像素进行操作,如:叠加.边框.怀旧.(高斯)模糊.锐化(拉普拉斯变换). Bitmap.getPixels(srcPixels, 0, width, 0, 0, width, height); newR = (int) (pixR * alpha + layR * (1 - alpha));    newR = Math.min(255, Math.max(0, newR));    ...    srcPixels[pos] = Color.argb(newA, ne

Canvas: trying to use a recycled bitmap [email&#160;protected]

近期在做和图片相关显示的出现了一个问题,整理一下思路.分享出来给大家參考一下: Exception Type:java.lang.RuntimeException java.lang.RuntimeException: Canvas: trying to use a recycled bitmap [email protected] at android.graphics.Canvas.throwIfCannotDraw(Canvas.java:1282) at android.view.GLE

Android 用Canvas画textview、bitmap、矩形(裁剪)、椭圆、线、点、弧

初始化对象 private Paint mPaint;//画笔 private int count;//点击次数 private Rect rect;//矩形 public CounstomView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); //初始化画笔 mPaint = new Paint(); rect = new Rect(); setOnClickListe

android:Canvas绘制自旋转Bitmap

需求 在SurfaceView或者普通View中,我们在每个绘制周期(onDraw)中,不仅需要更新绘制Bitmap对象在View中得位置,而且还希望Bitmap能够以它自身的中心点为圆心,进行自旋转. 解决 使用Canvas的drawBitmap(Bitmap bitmap,Matrix matrix,Paint paint)方法,最重要的就是定制Matrix. 代码如下: /** * 绘制自旋转位图 * * @param canvas * @param paint * @param bitm

Android中Canvas绘图基础详解(附源码下载)

Android中,如果我们想绘制复杂的自定义View或游戏,我们就需要熟悉绘图API.Android通过Canvas类暴露了很多drawXXX方法,我们可以通过这些方法绘制各种各样的图形.Canvas绘图有三个基本要素:Canvas.绘图坐标系以及Paint.Canvas是画布,我们通过Canvas的各种drawXXX方法将图形绘制到Canvas上面,在drawXXX方法中我们需要传入要绘制的图形的坐标形状,还要传入一个画笔Paint.drawXXX方法以及传入其中的坐标决定了要绘制的图形的形状

Android自定义View和Canvas绘图解析

自定义view的流程分为measure. layout.draw三个主要步骤,今天我们通过源码来分下下measure的过程 我们从顶级view开始,顶级view即DecorView, view的事件都是先经过这个DecorView, 接下来我们来看看这个DecorView的MeasureSpec的创建过程: ViewRoot 对应 ViewRootImpl类,  是连接WindowManager 和 DecorView的纽带,   进入ViewRootImpl中,查看measureHierarc