Matrix旋转bitmap一些坑

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/lift_class/article/details/62424019

废话: 今天写了一个音乐播放器中CD旋转的View,其中在旋转Bitmap的时候发现一些问题,记录一下,也希望帮到有一样困惑的朋友

我要将一张CD图片的bitmap不断的旋转,达到预期效果

一开始在网上找了一下实现旋转bitmap的方法

通过Matrix来旋转bitmap:
        Bitmap oldBmp = .....
        // 矩阵对象  
        Matrix matrix = new Matrix();  
        // 顺时针45度,默认中心点为旋转点
        // 此处matrix.setRotate也行,因为没有其他的变化叠加,若叠加必须用post
        matrix.postRotate(45);  
        // 创建新的bitmap
        Bitmap newBmp = Bitmap.createBitmap(
            oldBmp, 0, 0, oldBmp.getWidth(), oldBmp.getHeight(), matrix, true);  
        // oldBmp是旋转之前的bitmap,(0,0)是开始截取点的坐标
        // (oldBmp.getWidth(), oldBmp.getHeight())是截止截取点的坐标
        // 这两个点是从旧bitmap截取内容,因为要整个旋转,所以是旧bitmap的所有内容

每次都生成一个经过旋转的bitmap,然后请求重绘,就达到了不断旋转的效果(界面要不断重绘就要疯狂的生成bitmap,效率实在差劲!不过先不考虑这个)

看起来很完美,不是么?但是如果你去试一试,将新得到的bitmap绘制在一个固定大小的区域内,你就会发现问题:

旋转45°得到的是这玩意儿:

问题所在

这个原因应该很好理解,bitmap永远是正方形的,你将他旋转45°之后,就如上图2,新的bitmap的宽高变成了旧bitmap的对角线那么长(即新bitmap实际上是变大了!),所以将新bitmap绘制在固定区域内,就会出现图3的情况。

那么如何解决呢,效果是要保证唱片在旋转的时候在中心就行了,其他的边角无关紧要

这个时候我灵光一闪,bitmap变大是因为正方形倒了,而圆形的区域是不会变大的

所以我
1. 记录圆形的直径cd,用新newBmp的宽高减去直径,得到多出来的距离d

  d = newBmp - cd;
  1. 将newBmp裁剪一下
  Bitmap bmp = Bitmap.createBitmap(newBmp, d / 2, d / 2, cd, cd);

这样就得到了中心圆,再将他绘制出来,就能保证圆一直在中心

OK既然搞定了那就跑一下?(预览图我就不发了…以为木有录屏)在跑的过程中又会出现如下问题:

  1. 中心圆区域的图像越来越模糊!不断旋转的情况下会变成一坨浆糊不忍直视
  2. 旋转的时候图像会上下左右明显的抖动

现在来分析一下:

  1. 这个很好理解,因为不断截取新生成的bitmap的一部分,这个截取的一部分又作为oldBmp去生成newBmp,如此循环,那么久导致每次截取的时候会较上一次更模糊
  2. 因为Bitmap.createBitmap(newBmp, d / 2, d / 2, cd, cd)每一个参数都是int类型,而d增长值有可能是奇数有可能是偶数,所以导致截取的区域会有像素偏差,也就导致了绘制到屏幕上会出现跳动的情况

那么怎么解决呢?

无解

当然是我无法解决了…这里只是暴露出这些问题,希望能帮到大家注意一下,而我实际上,直接继承ImageView去写这个CD唱片的旋转效果了…

阅读更多

没有更多推荐了,返回首页