Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rotate image without shrinking on Android

I need to create a compass on an app i am working on. So i tried to create a new view called CompassView which basically extends imageview, shows a bitmap that has east west north south pointed on it, uses sensors to find the degrees the phone is pointed at, and rotate the image accordingly so that it would create an actual compass. But the problem is if i try to rotate the image to some angles like 45 degrees, it shrinks down. Here are some images to explain it better.

This is normal

This is shrinked

As you can see, the second image is shrinked down when i try to rotate around 45. What i want it to do is this: this

Here is the code i am currently using:

        Bitmap bMap = BitmapFactory.decodeResource(getResources(),
                R.drawable.compass);
        Matrix xMatrix = new Matrix();
        xMatrix.reset();
        xMatrix.postRotate(360-mValue, 75, 75); //This is 75 because 150 is the image width
        Bitmap bMapRotate = Bitmap.createBitmap(bMap, 0, 0,
                bMap.getWidth(), bMap.getHeight(), xMatrix, true);
        setImageBitmap(bMapRotate);

Any help would be appreciated. THanks

EDIT: (SOLUTION) I finally got it working thanks to the accepted answer. Here is the code i am using for anyone who wants to know how it worked:

RotateAnimation rAnimAntiClockWise = new RotateAnimation(
                    360 - mValue, 360 - event.values[0],
                    Animation.RELATIVE_TO_SELF, 0.5f,
                    Animation.RELATIVE_TO_SELF, 0.5f);
//mValue is the angle in degrees and i subtracted it from 360 to make it anticlockwise, and event.values[0] is the same thing as mValue
rAnimAntiClockWise.setFillAfter(true);
rAnimAntiClockWise.setInterpolator(new LinearInterpolator());
rAnimAntiClockWise.setDuration(0);
startAnimation(rAnimAntiClockWise);
like image 317
KSubedi Avatar asked Apr 02 '12 04:04

KSubedi


2 Answers

The issue is that your new image is actually larger, due to the corners of the source "sticking out", and so the view is scaling it down to fit.

A few possible approaches:

  1. After the above code, call Bitmap.createBitmap(Bitmap source, int x, int y, int width, int height), copying the center region of the correct size. Easy given the code you have, but creates a useless intermediate bitmap.

  2. Instead of giving the transform and source image to createBitmap, just create a mutable Bitmap of the correct size , wrap it in a Canvas , and tell the Canvas to render the rotated image .

    bMapRotate = Bitmap.createBitmap(
        bMap.getWidth(), bMap.getHeight(), bMap.getConfig());
    Canvas canvasRotate = new Canvas(bMap);
    canvasRotate.drawBitmap(bMap, xMatrix, paint); // any opaque Paint should do
    
  3. Keep the code you have, but tell the view to crop rather than scale when rendering.

like image 23
Laurence Gonsalves Avatar answered Oct 06 '22 01:10

Laurence Gonsalves


You can use a alternative trick which will work like same as rotate and doesn't resize the image. I actually rotate the image with 45 degree angle and remain changes after animation.

rAnimAntiClockWise = new RotateAnimation(0.0f, 45.0f,
                Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,
                0.5f);
        rAnimAntiClockWise.setFillAfter(true);
        rAnimAntiClockWise.setInterpolator(new LinearInterpolator());       
            bitmap = BitmapFactory.decodeResource(getResources(),
                    R.drawable.rotate);     
        rAnimAntiClockWise.setDuration(100);
        img_rotate.startAnimation(rAnimAntiClockWise);
like image 105
Maneesh Avatar answered Oct 06 '22 01:10

Maneesh