关于Bitmap的旋转

本文介绍了一种解决图片旋转过程中尺寸发生变化的方法。通过二次裁剪确保旋转前后图片大小一致,避免了因缩放造成的显示差异。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在原来的项目里有表盘指针旋转的需求,做出来的效果被我查出一个小小bug:
先贴代码:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
public void setRotate(float degrees)
{
    Bitmap s = BitmapFactory.decodeResource(this.getResources(),
                R.drawable.watch_stick_blue);   

    Matrix matrix = new Matrix();
    float scale = (float) (container.getLayoutParams().height)/ s.getHeight();
    matrix.preScale(scale, scale);
    matrix.postRotate(degrees);
    Bitmap ns = Bitmap.createBitmap(s, 0, 0, s.getWidth(), s.getHeight(), matrix, true);
    if (degrees != 0)
    {
        s.recycle();
    }
    stick.setImageBitmap(ns);
    RotateAnimation ra = AnimFactory.createRotateAnimation(-degrees - 146,
            0, Animation.RELATIVE_TO_SELF, 0.5f,
            Animation.RELATIVE_TO_SELF, 0.5f, 1500);
    ra.setInterpolator(new AccelerateDecelerateInterpolator());
    stick.startAnimation(ra);
}

他的做法是

一、s = BitmapFactory.decodeResource(this.getResources(), R.drawable.watch_stick_blue);
二、设Matrix matrix = new Matrix(); matrix可设scale translate rotate等属性
三、Bitmap ns = Bitmap.createBitmap(s, 0, 0, s.getWidth(), s.getHeight(), matrix, true);

这种做法可以实现旋转,但是我发现这种做法会使图像大小变化,

可以看出90度的时候的指针明显比45度的时候长,而在我去掉代码中matrix对scale的缩放以及在xml里对布局的控制之后
截图如下:



可以看出,此时指针长度相等,但是45度时候的图片比原图片变大了,究其原因,是因为createBitmap(Bitmap source, int x, int y, int width, int height, Matrix m, boolean filter)是先将source源文件按参数width和height从坐标x、y处截取,然后根据matrix进行转换,这样就可以理解,无论是在matrix里进行了缩放还是在xml里对图的大小进行控制,旋转后的新图中的指针会和原来的指针大小不同

所以目前来说我想到的办法是,**鉴于项目中的指针图片为正方形**,对第一次createBitmap做出的图S2再进行一次截取,判断后根据S1和S2较小的边最为最新截图的边,以保证图形大小相仿。
代码如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
public void setRotate(float degrees, boolean isCcurrentLeftTab, int index)
{
    Bitmap s = BitmapFactory.decodeResource(this.getResource(),R.drawable.watch_stick_blue);
    Matrix matrix = new Matrix();
    matrix.postRotate(degrees);
    Bitmap ns = Bitmap.createBitmap(s, 0, 0, s.getWidth(), s.getHeight(),
                matrix, true);
    if (degrees != 0)
    {
        s.recycle();
    }

    Matrix matrix2 = new Matrix();
    Bitmap nns;
    if(ns.getWidth()>s.getWidth() && ns.getHeight()>s.getHeight()){
        nns = Bitmap.createBitmap(ns, 
                (ns.getWidth()-s.getWidth())/2, 
                (ns.getHeight()-s.getHeight())/2, 
                s.getWidth(), s.getHeight(),
                matrix2, true);
    }else if(ns.getWidth()>s.getWidth() && ns.getHeight()<=s.getHeight()){
        nns = Bitmap.createBitmap(ns, 
                (ns.getWidth()-s.getWidth())/2, 
                0, 
                s.getWidth(), ns.getHeight(),
                matrix2, true);
    }else if(ns.getWidth()<=s.getWidth() && ns.getHeight()>s.getHeight()){
        nns = Bitmap.createBitmap(ns, 
                0, 
                (ns.getHeight()-s.getHeight())/2, 
                ns.getWidth(), s.getHeight(),
                matrix2, true);
        ns.recycle();
    }else{
        nns = Bitmap.createBitmap(ns, 
                0, 
                0, 
                ns.getWidth(), ns.getHeight(),
                matrix2, true);
    }
    stick.setImageBitmap(nns);
    stick.setBackgroundColor(Color.CYAN);
}

还不成熟,欢迎指正~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值