27

I want to Rotate Image according to a specific angle in android ,some thing like a compass...

I have this code...it works on drawPath() but i want to replace the path and the Drawing thing with image.. I tried to create a bitmap image ,DrawBitmapImage , but the image does not Rotate like the path..Any Help PLease?

public void draw(Canvas canvas) {
    double angle = calculateAngle(currentLongitude, currentLatitude, targetLongitude, targetLatitude);

    //Correction;
    angle-=90;

    //Correction for azimuth
    angle-=azimuth;

    if((getContext() instanceof Activity) && ((Activity)getContext()).getWindowManager().getDefaultDisplay().getOrientation()==Configuration.ORIENTATION_PORTRAIT)angle-=90;

    while(angle<0)angle=angle+360;

    Rect rect = canvas.getClipBounds();

    int height = rect.bottom-rect.top;
    int width = rect.right-rect.left;
    int left = rect.left;
    int top = rect.top;

    if(height>width){
        top+=(height-width)/2;
        height=width;
    }
    if(width>height){
        left+=(width-height)/2;
        width=height;
    }

    float centerwidth = width/2f;
    float centerheight = height/2f;

    Paint p = new Paint();
    p.setColor(color);
    p.setStyle(Paint.Style.FILL);
    p.setAntiAlias(true);

    float startX = left+(float)(centerwidth+Math.cos(deg2rad(angle))*width/3.0);
    float startY = top+(float)(centerheight+Math.sin(deg2rad(angle))*height/3.0);

    Path path = new Path();
    path.moveTo(
            startX,
            startY);
    path.lineTo(
            left+(float)(centerwidth+Math.cos(deg2rad(angle+140))*width/4.0),
            top+(float)(centerheight+Math.sin(deg2rad(angle+140))*height/4.0));
    path.lineTo(
            left+(float)centerwidth,
            top+(float)centerheight
            );
    path.lineTo(
            left+(float)(centerwidth+Math.cos(deg2rad(angle+220))*width/4.0), 
            top+(float)(centerheight+Math.sin(deg2rad(angle+220))*height/4.0)
            );

    path.lineTo(
            startX,
            startY
            );




    canvas.drawPath(path, p);
}
Simon Sarris
  • 62,212
  • 13
  • 141
  • 171
Reham
  • 1,916
  • 6
  • 21
  • 45

6 Answers6

55

You can either rotate your bitmap when you draw it by using a matrix:

Matrix matrix = new Matrix();
matrix.setRotate(angle, imageCenterX, imageCenterY);
yourCanvas.drawBitmap(yourBitmap, matrix, null);

You can also do it by rotating the canvas before drawing:

yourCanvas.save(Canvas.MATRIX_SAVE_FLAG); //Saving the canvas and later restoring it so only this image will be rotated.
yourCanvas.rotate(-angle);
yourCanvas.drawBitmap(yourBitmap, left, top, null);
yourCanvas.restore();

Pick the one that suits you the best.

Jave
  • 31,598
  • 14
  • 77
  • 90
  • @Jave, I think the first approach can be used, in particular, where you want to rotate an image or bitmap around x-axis and/or y-axis as `Canvas` doesn't have rotation methods other than the one which does it in XY-plane. I think one can get a `Camera` object and make necessary 3D transformations and finally use `getMatrix` passing `Matrix` instance to get the corresponding `Matrix` representation. Lastly, pass this `Matrix` to `drawBitmap` method. Specifically, [here](http://stackoverflow.com/questions/32554925/android-animate-rotation-of-map-marker-around-x-and-y-axis): Any thoughts. Thanks! – Kevin Ghaboosi Sep 19 '15 at 20:45
5

You have to rotate the canvas first and then draw whatever you want. Then the object drawn will be appeared as rotated on screen.

canvas.rotate(45); // degrees to rotate

try this its good way.

Check this tutorial you will get information about how to draw bitmap and how to rotate canvas

Check complete tutorial

Yugandhar Babu
  • 10,311
  • 9
  • 42
  • 67
  • Rotate the canvas according to the angle? Then what? Just creating Bitmap and draw it – Reham Jan 03 '12 at 13:07
  • it seem to be you didn't read information available at Android Developers website. In Canvas class many functions are available to draw Bitmap. You have to call any drwaBitmap() after canvas.rotate() according to your requirement. – Yugandhar Babu Jan 03 '12 at 13:13
  • @Reham did you checked the link ? Did you got solution to your problem ? if my answer/suggestion solves your problem please mark it as answer. bye :-) – Yugandhar Babu Jan 03 '12 at 15:33
  • I checked your answer and thank you very much..i think its the right solution...but until now i'm stuck in the same problem...the image is rotating around the screen...i don't have much experience in canvas and the drawing thing..:( – Reham Jan 03 '12 at 20:11
  • this code solved my problem a little...:) Matrix mtx = new Matrix(); b=BitmapFactory.decodeResource(this.getResources(),R.drawable.arrow) ; mtx.reset(); mtx.setTranslate(rect.exactCenterX(),rect.exactCenterY()); mtx.postRotate((float)angle,rect.exactCenterX(),rect.exactCenterY()); canvas.drawBitmap(b, mtx,p); – Reham Jan 04 '12 at 20:05
2

This is the only one that worked for me with no problem.

    private Bitmap rotateBitmap(Bitmap bitmap, int rotationAngleDegree){

        int w = bitmap.getWidth();
        int h = bitmap.getHeight();

        int

 newW=w, newH=h;
    if (rotationAngleDegree==90 || rotationAngleDegree==270){
        newW = h;
        newH = w;
    }
    Bitmap rotatedBitmap = Bitmap.createBitmap(newW,newH, bitmap.getConfig());
    Canvas canvas = new Canvas(rotatedBitmap);

    Rect rect = new Rect(0,0,newW, newH);
    Matrix matrix = new Matrix();
    float px = rect.exactCenterX();
    float py = rect.exactCenterY();
    matrix.postTranslate(-bitmap.getWidth()/2, -bitmap.getHeight()/2);
    matrix.postRotate(rotationAngleDegree);
    matrix.postTranslate(px, py);
    canvas.drawBitmap(bitmap, matrix, new Paint( Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG | Paint.FILTER_BITMAP_FLAG ));
    matrix.reset();

    return rotatedBitmap;
}
MSaudi
  • 4,442
  • 2
  • 40
  • 65
2

Based on @Sakthi 's code, but add scaling :)

        Rect rect = new Rect(0,0,canvas.getWidth(), canvas.getHeight());
        Matrix matrix = new Matrix();
        matrix.postTranslate(-bitmap.getWidth()/2, -bitmap.getHeight()/2);
        matrix.postScale(
                ((float)rect.width()) / bitmap.getWidth(),
                ((float)rect.height()) / bitmap.getHeight());
        matrix.postRotate(180);
        matrix.postTranslate(rect.exactCenterX(), rect.exactCenterY());
        canvas.drawBitmap(bitmap, matrix, null);
ch271828n
  • 15,854
  • 5
  • 53
  • 88
1

Use following code. it worked for me

float rotation = 30.0f;

     Bitmap bitmap = your bitmap
     Rect rect = new Rect(100,100,bitmap.width, bitmap.height);
     Matrix matrix = new Matrix();
     float px = rect.exactCenterX();
     float py = rect.exactCenterY();
     matrix.postTranslate(-bitmap.getWidth()/2, -bitmap.getHeight()/2);
     matrix.postRotate(rotation);
     matrix.postTranslate(px, py);
     canvas.drawBitmap(bitmap, matrix, null);
     matrix.reset();
     invalidate();
Sakthivel Appavu
  • 565
  • 5
  • 24
1

@Reham: Look at this example code below,

public class bitmaptest extends Activity {
@Override
public void onCreate(Bundle icicle) {
    super.onCreate(icicle);
    LinearLayout linLayout = new LinearLayout(this);

    // load the origial BitMap (500 x 500 px)
    Bitmap bitmapOrg = BitmapFactory.decodeResource(getResources(),
           R.drawable.android);

    int width = bitmapOrg.width();
    int height = bitmapOrg.height();
    int newWidth = 200;
    int newHeight = 200;

    // calculate the scale - in this case = 0.4f
    float scaleWidth = ((float) newWidth) / width;
    float scaleHeight = ((float) newHeight) / height;

    // createa matrix for the manipulation
    Matrix matrix = new Matrix();
    // resize the bit map
    matrix.postScale(scaleWidth, scaleHeight);
    // rotate the Bitmap
    matrix.postRotate(45);

    // recreate the new Bitmap
    Bitmap resizedBitmap = Bitmap.createBitmap(bitmapOrg, 0, 0,
                      width, height, matrix, true);

    // make a Drawable from Bitmap to allow to set the BitMap
    // to the ImageView, ImageButton or what ever
    BitmapDrawable bmd = new BitmapDrawable(resizedBitmap);

    ImageView imageView = new ImageView(this);

    // set the Drawable on the ImageView
    imageView.setImageDrawable(bmd);

    // center the Image
    imageView.setScaleType(ScaleType.CENTER);

    // add ImageView to the Layout
    linLayout.addView(imageView,
            new LinearLayout.LayoutParams(
                  LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT
            )
    );

    // set LinearLayout as ContentView
    setContentView(linLayout);
}
}

you have to use the matrix to rotate image look the lines

matrix.postRotate(45); -

this will rotate the image to 45 degrees

Hope this help you ...thx

WarrenFaith
  • 57,492
  • 25
  • 134
  • 150
optimus
  • 729
  • 2
  • 12
  • 36