StarSoul

学历代表过去,能力代表现在,学习力代表未来!
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

自适应绘制图像

Posted on 2011-11-22 17:57  StarSoul  阅读(315)  评论(0)    收藏  举报

背景: 使用SurfaceView通过标准的Canvas方法直接操作图像像素进行绘图, View的大小不固定是可以改变的(这里假设View的宽度为ViewWidth,View的高度为ViewHeight)。需要显示的图像的大小也不确定(这里假设图像的宽度为ImageWidth,图像的高度为ImageHeight)。

问题:如何自适应的在每次绘制时图像正好画到View的正中央。

这里绘制图像用到的是标准的Canvas的方法:

Public void drawBitmap (int[] colors, int offset, int stride, float x, float y, int width, int height, boolean hasAlpha, Paint paint)

Treat the specified array of colors as a bitmap, and draw it. This gives the same result as first creating a bitmap from the array, and then drawing it, but this method avoids explicitly creating a bitmap object which can be more efficient if the colors are changing often.

colors Array of colors representing the pixels of the bitmap
offset Offset into the array of colors for the first pixel
stride The number of colors in the array between rows (must be >= width or <= -width).
x The X coordinate for where to draw the bitmap
y The Y coordinate for where to draw the bitmap
width The width of the bitmap
height The height of the bitmap
hasAlpha True if the alpha channel of the colors contains valid values. If false, the alpha byte is ignored (assumed to be 0xFF for every pixel).
paint May be null. The paint used to draw the bitmap

这个问题实际上要求我们每次绘制时要能正确指定如下两个数值:

1. Canvas的缩放率Scale的值。

2. Canvas上画图像的起始点坐标值(即上文drawBitmap的x,y参数)。

考虑最简单的情况:ViewWidth>=ImageWidth && ViewHeight>=ImageHeight。很明显,这种情况下Scale=1,x=(ViewWidth-ImageWidth)/2,y=(ViewHeight-IH)/2。

考虑需要缩放画布的情况:ViewWidth<ImageWidth || ViewHeight<ImageHeight,要使图像能够完整的显示于View的正中,需要缩小,缩放率的确定跟图像的宽高比率(ImageWidth/ImageHeight)和View控件的宽高比率(ViewWidth/ViewHeight)有关系:

如果ViewWidth/ViewHeight>=ImageWidth/ImageHeight,缩放率应以ViewHeight为基准,Scale=ViewHeight/ImageHeight;

如果ViewWidth/ViewHeight<ImageWidth/ImageHeight,缩放率应以ViewWidth为基准,Scale=ViewWidth/ImageWidth。

起始坐标值如何确定呢?因为图像要显示在中央,图像缩放时需要以(ViewWidth/2, ViewHeight/2)为中心点进行缩放,这样Canvas坐标原点(0,0)就会从默认的View左上角位置进行平移。另外drawBitmap()方法的x,y参数指的是画布没有进行任何缩放,平移或旋转等转换操作的情况下的坐标值,假如图像进行了缩放,则在Canvas上画图像的实际起始点坐标值是受到偏移后的坐标原点和scale值的影响的。

                                                              

基于以上理论,我们可以知道Canvas上图像的起始点坐标值的确定仍然是x=(ViewWidth-ImageWidth)/2,y=(ViewHeight-IH)/2,它具有一般性。