学习了jxt1234and2010的大作,试着用自己的理解去分析skia draw bitmap的过程,在这里感谢jxt1234and2010。
1.Draw bitmap api
这里主要讲一下在SkCanvas中,有哪些draw bitmap 的API可用,以及各自的作用是什么。
draw bitmap的api有以下几种:
- drawBitmap:将bitmap画到x,y的位置(这本身是一个平移,需要和SkCanvas中的矩阵状态叠加)。
- drawBitmapRect 和 drawBitmapRectToRect:将源图src矩阵部分,画到目标dst区域去。最后一个flags是AndroidL上为了gpu绘制效果而加上去的,在CPU绘制中不需要关注。
- drawSprite:无视SkCanvas的矩阵状态,将bitmap平移到x,y的位置。
- drawBitmapMatrix:绘制的bitmap带有matrix的矩形变换,需要和SkCanvas的矩形变换叠加。
- drawRect:这个是最通用的方法,多用于需要加入额外效果的场景,比如需要绘制重复纹理。关于Tile的两个参数就是OpenGL纹理贴图中水平垂直方向上的边界处理模式。
根据以下测试代码来直观看一下这些api的不同:
<pre name="code" class="cpp">SkBitmap src;
SkImageDecoder::DecodeFile("E:/git/skia/Skia_VS2010/skia/out/2.png", &src);
/*各种绘制图片方法使用示例*/
{
canvas->drawBitmap(src, 0, 0, NULL); //在目的设备的(0,0)位置绘制解码出的图片bitmap
}
{
canvas->drawSprite(src, 400, 400, NULL); //简易模式下,平移到目的设备的(400,400)处绘制解码后的图片
}
{
canvas->drawBitmap(src, 0, 0, NULL);
SkRect dstR;
dstR.set(60,60,110,110);
SkRect srcR;
srcR.set(0,0,50,50);
canvas->drawBitmapRectToRect(src, &srcR, dstR, NULL); //将源区域内的bitmap绘制到目的区域
}
{
SkMatrix m;
m.setScale(2.3,0.9);
canvas->drawBitmapMatrix(src, m, NULL); //按照m矩阵绘制bitmap
}
{
SkRect dstRect;
dstRect.set(100,100,920,480); //绘制区域
SkPaint paint;
SkMatrix m;
m.setScale(2.3,0.9);
SkShader* shader = SkShader::CreateBitmapShader(src, SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode, &m); //重复贴图
paint.setShader(shader);
SkSafeUnref(shader);
canvas->drawRect(dstRect, paint);
}
2.Draw bitmap flow
通过调