背景: 使用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,它具有一般性。
浙公网安备 33010602011771号