andbook!.pdf - Learning Android Get an anddev.org - Android-Shirt Back to index
anddev.org Header Logo
FAQ Search Top rated articles Browse Feeds anddev.org - Authors Contact Details Register Log in

Resize and Rotate Image - Example


 
       anddev.org - Android Development Community | Android Tutorials | Index -> Novice Tutorials
Author Message
mauri
Junior Developer
Junior Developer


Joined: 04 Dec 2007
Posts: 13

PostPosted: Mon Jan 21, 2008 5:28 pm    Post subject: Resize and Rotate Image - Example Reply with quote

Resize and Rotate Image - Example


What you learn: You will learn how to rotate ans resize images(Bitmaps) using a Matrix.

Question Problems/Questions: Write them right below...

Difficulty: 1 of 5 Smile

The source:
Java:
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);
    }
}



android.png
 Description:
Image for the Example
 Filesize:  24.2 KB
 Viewed:  48427 Time(s)

android.png


Back to top
View user's profile Send private message
plusminus
Site Admin
Site Admin


Joined: 14 Nov 2007
Posts: 2660
Location: College Park, MD

PostPosted: Mon Jan 21, 2008 5:37 pm    Post subject: Reply with quote

Hello mauri,

thx for sharing your code, never realized the Matrix-Parameter in Bitmap.createBitmap, is damn useful Smile

Best Regards,
plusminus

PS: Added some introducing lines to your code

_________________
Download my apps Idea
Please remember, that this board is give & take Smile


| Android Development Community / Tutorials
Back to top
View user's profile Send private message Send e-mail Visit poster's website
venkat
Senior Developer
Senior Developer


Joined: 27 Nov 2007
Posts: 152
Location: India

PostPosted: Tue Jan 22, 2008 6:08 am    Post subject: Reply with quote

Thanks mauri, this is what exactly i am looking for.
_________________
Regards,
Venkat.
Back to top
View user's profile Send private message
ecelino
Once Poster
Once Poster


Joined: 18 Feb 2008
Posts: 1

PostPosted: Fri Mar 21, 2008 8:22 pm    Post subject: real time transformation Reply with quote

thank you. i've been looking for this code.

but this is a bit expensive in processing and memory usage. it will be a lot better if we can do this in real time. does anyone knows how?

i am trying to create a game and i used BitmapDrawable to hold my .png images. i need a way to transform my BitmapDrawable objects in real time without creating new BitmapDrawable whenever i want to transform the image.

also, does anyone knows how to apply transformation to an existing BitmapDrawble object? again, without creating new one.

thank you very much.
Back to top
View user's profile Send private message
chonada
Once Poster
Once Poster


Joined: 03 Mar 2008
Posts: 1

PostPosted: Fri Mar 28, 2008 9:23 am    Post subject: Rotating using matrix continuously shrinks the image. Reply with quote

I am doing a photoeditor application and we have a button to rotate the image in the canvas (which is actually an image switcher), now while i did the rotation using the Matrix, i found that the image is shrinking when rotating (noticeable when rotating continuously), code snippet given below, any suggestions will be appreciated.
Java:

mSwitcher.setDrawingCacheEnabled(true);         // mSwitcher is the ImageSwitcher
bmp = mSwitcher.getDrawingCache();
aMatrix = new Matrix();
aMatrix.setRotate(90.0f);
flippedBmp = Bitmap.createBitmap(bmp, 0, 0, bmp.width(), bmp.height(), aMatrix, false);
mSwitcher.setImageDrawable(new BitmapDrawable(flippedBmp));
mSwitcher.setDrawingCacheEnabled(false);

Thanx in advance.
Back to top
View user's profile Send private message
plusminus
Site Admin
Site Admin


Joined: 14 Nov 2007
Posts: 2660
Location: College Park, MD

PostPosted: Fri Mar 28, 2008 2:19 pm    Post subject: Reply with quote

Hello chonada,

maybe this is a float-number accuracy problem, as if 90.0f ~= 90 Confused

Regards,
plusminus

_________________
Download my apps Idea
Please remember, that this board is give & take Smile


| Android Development Community / Tutorials
Back to top
View user's profile Send private message Send e-mail Visit poster's website
wonderoid
Junior Developer
Junior Developer


Joined: 16 Feb 2008
Posts: 10

PostPosted: Fri Mar 28, 2008 3:55 pm    Post subject: Re: real time transformation Reply with quote

ecelino wrote:
thank you. i've been looking for this code.

but this is a bit expensive in processing and memory usage. it will be a lot better if we can do this in real time. does anyone knows how?

i am trying to create a game and i used BitmapDrawable to hold my .png images. i need a way to transform my BitmapDrawable objects in real time without creating new BitmapDrawable whenever i want to transform the image.

also, does anyone knows how to apply transformation to an existing BitmapDrawble object? again, without creating new one.

thank you very much.

Modifying the rotation/ scaling of the canvas you are drawing on should do it. I used it for drawing paths, and don't know if it will work for bitmaps but why wouldn't it? C being a canvas object you can
Java:
c.scale(scaleFactorX, scaleFactorY);
c.translate(dX, dY);

and also rotate it.
(Btw do not forget to push your current state into stack otherwise you will be altering the canvas cumulatively, probably not what you want. It is simply;
Java:
     canvas.save();
        // do whatever
     canvas.restore();

)
Back to top
View user's profile Send private message
kiran
Experienced Developer
Experienced Developer


Joined: 22 Nov 2007
Posts: 78
Location: India

PostPosted: Tue Apr 01, 2008 6:42 am    Post subject: Reply with quote

Hi,

Using this code, the image displayed is resized again to 600x600 on a keypress Now the initial values of x and y are not correct. The image gets displayed starting from the x,y coordinates of the previously displayed image. And if an image with bigger dimension is rotated the application crashes after some continuous rotations. pls help..

Thanks in andvance

_________________
Smile smile it is the key that fits the lock of everybody's heart
Back to top
View user's profile Send private message
rahul_mawkins
Developer
Developer


Joined: 27 Feb 2008
Posts: 34

PostPosted: Wed Apr 02, 2008 12:29 am    Post subject: great rotating the canvas rotates the image now???? Reply with quote

How do we rotate the canvas with angle x so that while moving the tip of the arrow is always in the path direction
i.e driving direction

Any help will be rewarded
cheers
RM
Back to top
View user's profile Send private message Yahoo Messenger
neel
Developer
Developer


Joined: 15 Feb 2008
Posts: 31
Location: San Jose

PostPosted: Thu Oct 23, 2008 4:46 am    Post subject: help with some modification to existing code Reply with quote

Hi,

i made a small modification just for testing purpose and need some help.

i basically have a for loop which goes from 1 to 5 and i want to see the image being rotated 5 times i.e once every time the for loop iterates from 1 to 5. basically i just give a call to 'make()' function which has the code for drawing and displaying the image.

however, when i run the code, i see the image being rotated only once. please can you help me resolve this. is there some function that i need to call explicitly every time to let the Android system display the image on screen for every rotation.

here is the code that i am testing.

Code:

package com.d5;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.graphics.drawable.BitmapDrawable;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup.LayoutParams;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.ImageView.ScaleType;


public class Test extends Activity {



   float degrees =0;
   Thread t;
    @Override
    public void onCreate(Bundle icicle) {
       android.util.Log.i("ACTIVITY STARTED", "start");
        super.onCreate(icicle);

       begin();

    }

    public void begin(){

    t = new Thread(){
          public void run(){
           android.util.Log.i("INSIDE RUN", "inside run");
         for ( int j = 1; j <=5; j++){// for starts

              android.util.Log.i("INSIDE FOR", "inside for");

               try{
               degrees+=10;
              android.util.Log.i("Degrees: ",String.valueOf(degrees));
                   make(degrees);
                android.util.Log.i("CAME BACK FROM MAKE", "");
                   // i just want the code to wait 3 sec before it rotates the image again
                   sleep(3000);
               }catch(Exception e){
                  e.printStackTrace();
               }

           }// for ends

       }// run ends

    };// thread ends

  t.start();


}// start ends

    public void make(float x){
       android.util.Log.i("INSIDE MAKE", "inside make");
        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(x);

        // 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 inearLayout as ContentView
        setContentView(linLayout);


        android.util.Log.i("GOING OUT OF MAKE", "going out of make");
    }

}



please help, thank you
Back to top
View user's profile Send private message Send e-mail
plusminus
Site Admin
Site Admin


Joined: 14 Nov 2007
Posts: 2660
Location: College Park, MD

PostPosted: Thu Oct 23, 2008 6:44 am    Post subject: Reply with quote

You should call setContentView only once in onCreate() Exclamation

You'd create a View (maybe extend ImageView), which has a method to draw its content rotated.

Best Regards,
plusminus

_________________
Download my apps Idea
Please remember, that this board is give & take Smile


| Android Development Community / Tutorials
Back to top
View user's profile Send private message Send e-mail Visit poster's website
neel
Developer
Developer


Joined: 15 Feb 2008
Posts: 31
Location: San Jose

PostPosted: Thu Oct 23, 2008 7:13 am    Post subject: Reply with quote

Hi plusminus,

is is possible for you to please provide some code snippet for doing that.

I initially had this code where on click of 'KEY_EVENT' i was able to rotate the image clockwise and anti-clockwise. I want to remove the KEY_EVENT and just make it work using a for loop.

Java:

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.graphics.drawable.BitmapDrawable;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.ViewGroup.LayoutParams;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ImageView.ScaleType;

public class bitmaptest extends Activity {
     float degrees =0;
    @Override
    public void onCreate(Bundle icicle) {
        super.onCreate(icicle);
        make(degrees);
    }
    public void make(float x){
     android.util.Log.i("INSIDE MAKE", "inside make");
        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(x);

        // 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);
        android.util.Log.i("GOING OUT MAKE", "going out make");
    }
    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
         
         if(keyCode==KeyEvent.KEYCODE_DPAD_UP)// rotate clockwise
             // zoomControler+=10;
          {
           degrees=degrees+10;
          make(degrees);
           //make(10);
           android.util.Log.i("ONE","rotating clockwise by "+String.valueOf(degrees)+" degrees");
           android.util.Log.i("DEGREES","current value "+String.valueOf(degrees)+" degrees");
          }
         
         
         if(keyCode==KeyEvent.KEYCODE_DPAD_DOWN) // rotate anti-clockwise
         {
           degrees=degrees-10;
           make(degrees);
           //make(10);
           android.util.Log.i("TWO","rotating anti-clockwise by "+String.valueOf(degrees)+" degrees");
           android.util.Log.i("DEGREES","current value "+String.valueOf(degrees)+" degrees");
           
         }
         
        // invalidate();
         return true;
    }
}
Back to top
View user's profile Send private message Send e-mail
weldrian
Junior Developer
Junior Developer


Joined: 09 Dec 2008
Posts: 23

PostPosted: Fri Dec 19, 2008 4:52 am    Post subject: do you have any idea, to make it smooth when rotating? Reply with quote

HI man, thx for the code above, i need that for reference,

i dont mind to click up and down for the rotation;
but do you have any idea, to make it smooth when rotating?
Back to top
View user's profile Send private message
Kevin Prichard
Once Poster
Once Poster


Joined: 24 Jan 2009
Posts: 1

PostPosted: Sat Jan 24, 2009 8:42 pm    Post subject: Re: Rotating using matrix continuously shrinks the image. Reply with quote

chonada wrote:
I am doing a photoeditor application and we have a button to rotate the image in the canvas (which is actually an image switcher), now while i did the rotation using the Matrix, i found that the image is shrinking when rotating (noticeable when rotating continuously), code snippet given below, any suggestions will be appreciated.
Java:

mSwitcher.setDrawingCacheEnabled(true);         // mSwitcher is the ImageSwitcher
bmp = mSwitcher.getDrawingCache();
aMatrix = new Matrix();
aMatrix.setRotate(90.0f);
[b]flippedBmp = Bitmap.createBitmap(bmp, 0, 0, bmp.width(), bmp.height(), aMatrix, false)[/b]
mSwitcher.setImageDrawable(new BitmapDrawable(flippedBmp));
mSwitcher.setDrawingCacheEnabled(false);

Thanx in advance.


chonada,

Assuming you are running the above code for each step of a rotation, you are first grabbing bmp from mSwitcher, then rotating it, then putting it back into mSwitcher, right? Once the bmp is rotated into flippedBmp, its dimensions are changed, and are greater. But I think that the classes used will fit the rotated image within the target drawing area, which means shrinking.

Think of the diagonal distances, from corner to corner: if you rotate bmp 45 deg, the width and height of flippedBmp are now greater than the original bmp.

You need to have a bmp that is at least as large as the maximum line distance found in the original bmp, in each dimension. Remember the Pythagorean theorem. With the original image spec of w * h, the image resulting from the rotation will need to be sqrt(w^2 + h^2) in both dimensions, to prevent shrinkage, to give it the maximum room needed to arbitrarily rotate without shrinking.

Try changing

Java:

flippedBmp = Bitmap.createBitmap(bmp, 0, 0, bmp.width(), bmp.height(), aMatrix, false)


to

Java:

flippedBmp = Bitmap.createBitmap(bmp, 0, 0, Math.hypot(bmp.width(), bmp.height()), Math.hypot(bmp.width(), bmp.height()), aMatrix, false)


This is just a wild guess, haven't run your code, but I have encountered this in the past.

_________________
Kevin Prichard
Software Engineer
Back to top
View user's profile Send private message
Display posts from previous:   
       anddev.org - Android Development Community | Android Tutorials | Index -> Novice Tutorials All times are GMT + 1 Hour
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


© 2007, Android Development Community
All rights reserved.
Powered by phpBB.