简体   繁体   中英

ImageView rotate without recreating the bitmap

I want to rotate an ImageView image. Here is my code:

Matrix mat = new Matrix();
mat.preRotate(90, ivImage.getWidth()/2, ivImage.getHeight()/2);
ivImage.setScaleType(ScaleType.MATRIX);
ivImage.setImageMatrix(mat);

but when I click on the rotate button, not only the image rotates, but it is scaled too, because the bitmap is larger then the ImageView .

I know I can use

b = Bitmap.createBitmap(b, 0, 0, b.getWidth(), b.getHeight(), mat, true);
ivImage.setImageBitmap(b);

but this is noticeably slower, and has some lag.

So my question is: how to rotate the image without being scaled and without recreating the bitmap?

Here is the code that I have used for rotation of image to 90 degrees.

         if(oldAngle == 0){
              newAngle = oldAngle + 90;
            }
            else if(oldAngle == 90)
                newAngle = oldAngle - 90;
              LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) view.getLayoutParams();
              int centerX = layoutParams.leftMargin + (view.getWidth()/2);
              int centerY = layoutParams.topMargin + (view.getHeight()/2);
              RotateAnimation animation = new RotateAnimation(oldAngle, newAngle, centerX, centerY);
              animation.setDuration(0);
              animation.setRepeatCount(2);
              animation.setFillAfter(true);
              view.startAnimation(animation);

              oldAngle = newAngle;

Hope it will help you...

How about using an XML animation?

<?xml version="1.0" encoding="utf-8"?>
    <rotate
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromDegrees="0"
    android:interpolator="@android:anim/linear_interpolator"
    android:toDegrees="360"
    android:pivotX="50%"
    android:pivotY="50%"
    android:duration="1000"
    android:startOffset="0"
    android:repeatCount="infinite"
    />

And then use it with something like;

 rotation = AnimationUtils.loadAnimation(this, R.anim.clockwise_rotation);
 buttonRefresh.startAnimation(rotation);

ps. This infinitely spins around. So needs some adjustments.

use this

final Random generator = new Random();
        int n = 10000;
        n = generator.nextInt(n);
        final Matrix mtx = new Matrix();
        mtx.postRotate(n);
        rotator = Bitmap.createBitmap(all, 0, 0,
                all.getWidth(), all.getHeight(), mtx,
                true);
        view.setImageBitmap(rotator);

this will rotate the image randomly. just change .nextInt(n) to .nextInt(AnyNumberYouLife) its fast :)

I found that for my purpose it was the best solution to use Canvas instead of ImageView . And for the rotating of the image I chose to use another library that can be found here

here's a nice solution for putting a rotated drawable for an imageView:

Drawable getRotateDrawable(final Bitmap b, final float angle) {
    final BitmapDrawable drawable = new BitmapDrawable(getResources(), b) {
        @Override
        public void draw(final Canvas canvas) {
            canvas.save();
            canvas.rotate(angle, b.getWidth() / 2, b.getHeight() / 2);
            super.draw(canvas);
            canvas.restore();
        }
    };
    return drawable;
}

usage:

Bitmap b=...
float angle=...
final Drawable rotatedDrawable = getRotateDrawable(b,angle);
root.setImageDrawable(rotatedDrawable);

another alternative:

private Drawable getRotateDrawable(final Drawable d, final float angle) {
    final Drawable[] arD = { d };
    return new LayerDrawable(arD) {
        @Override
        public void draw(final Canvas canvas) {
            canvas.save();
            canvas.rotate(angle, d.getBounds().width() / 2, d.getBounds().height() / 2);
            super.draw(canvas);
            canvas.restore();
        }
    };
}

also, if you wish to rotate the bitmap, but afraid of OOM, you can use an NDK solution i've made here

I've found the easiest way to rotate an ImageView is to do this:

view.animate().rotationBy(degrees);

Very easy to implement and android handles all the rest

Hope this helps! :)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM