BlackBerry Forums Support Community               

Closed Thread
 
LinkBack Thread Tools
Old 11-06-2010, 10:35 AM   #1 (permalink)
New Member
 
Join Date: Nov 2010
Model: 7100
PIN: N/A
Carrier: I'm not gonna let you know this one
Posts: 2
Post Thanks: 0
Thanked 0 Times in 0 Posts
Default rotate a bitmap (help needed)

Please Login to Remove!

Hi everyone.

I have the following method:

Code:
 public static Bitmap rotateImage(Bitmap oldB, int angle) throws Exception
    {
        int w = oldB.getWidth();
        int h = oldB.getHeight();
        
        double angRad = (angle % 360)*(Math.PI/180);
        Bitmap newB = new Bitmap(w,h);
        
        int[] oldD = new int[w*h];
        int[] newD = new int[w*h];
        
        oldB.getARGB(oldD, 0, w, 0, 0, w, h);
        
        int axisX = w/2;
        int axisY = h/2;
        
        for(int x = 0; x < oldD.length; x++)
        {
            int oldX = x%w;
            int oldY = x/w;
            int op = oldX-axisX;
            int adj = oldY-axisY;
            
            double oldT = MathUtilities.atan2(op, adj);
            double rad = Math.sqrt((op*op)+(adj*adj));
            double newT = oldT+angRad;
            
            int newX = (int)MathUtilities.round((rad*Math.sin(newT))+(double)axisX);
            int newY = (int)MathUtilities.round((rad*Math.cos(newT))+(double)axisY);
            
            if(newX<0||newY<0||newX>=w||newY>=h)
            {
                newD[x] = 0x00000000;
            }
            else
            {
                newD[x] = oldD[(newY*w)+newX];
            }
        }
        
        newB.setARGB(newD, 0, w, 0, 0, w, h);
        return newB;
    }
And I am using it like this:

Code:
rotateImage(givenImage, 90);
It is not doing anything. Can someone please tell my why?
Thanks very much.
Offline  
Old 11-07-2010, 07:47 AM   #2 (permalink)
New Member
 
Join Date: Nov 2010
Model: 7100
PIN: N/A
Carrier: I'm not gonna let you know this one
Posts: 2
Post Thanks: 0
Thanked 0 Times in 0 Posts
Default

ok, let me give a detailed description of the problem. I have two java files and one image:

Code:
/**
 * AnimationScreen.java
 *
 * Author:  Mark Sohm
 *
 */

package com.msohm.animationDemo;

import net.rim.device.api.system.Bitmap;
import net.rim.device.api.ui.container.FullScreen;
import net.rim.device.api.ui.Graphics;
import net.rim.device.api.system.Characters;
import net.rim.device.api.ui.UiApplication;
import java.util.Date;
import net.rim.device.api.ui.component.Dialog;
import net.rim.device.api.system.Alert;
import net.rim.device.api.util.MathUtilities;


//Optimized avg fps 7100 = 34, 7290 sim = 51 - this wasn't so good after all.  :)
//Non optimized (draw house/sun, no clearAll) avg fps 7100 = 17, 7290 sim = 51
//Non optimized (using invalidate, no _drawHouse = false) avg fps 7100 = 25, 7290 sim = 51
//Non optimized (using invalidate, no _drawHouse = false, not overriding paintBackground) avg fps 7100 = 25, 7290 sim = 51
// - but without overriding it things have to be redrawn every time.
//Can't test with just using invalidate vs calling paint directly or else
//the entire screen is cleared.
//Optimized (using invalidate(#, #, #, #), not overriding paintBackground, no clearAll, _drawHouse/sun) 
//  avg fps 7100 = 51, 7290 sim = 51
//Optimized using invalidate(####), using _drawHouse saves ~ 400 ms per animation vs no _drawHouse.

public class AnimationScreen extends FullScreen
{
    
    private final static boolean SHOW_FRAMERATE = true;  //Controls the showing of the framerate dialog.
    
    //Images.

    private final static Bitmap brick = Bitmap.getBitmapResource("brick.png");
    
    private int _frameNo;  //The current frame number.    
    private int _runnerXVal;  //X coordinate of the runner.
    private int _runnerFrame;  //The current frame of the runner.
    private boolean _currentlyAnimating;  //Set to true if an animation is in progress.
    
    //Boolean variables to control what is drawn on the screen.
    private boolean _drawRunner;
    
    public AnimationScreen()
    {
        super();
        initialize();
    }
    
    //Initialize variables to their starting values.
    private void initialize()
    {
        _drawRunner = true;
        _frameNo = 0;
        _runnerFrame = 0;
        
        //Draw the screen in its initial state.
        invalidate();
    }
    
    private class AnimationThread extends Thread
    {
        
        Date rightNow = new Date();
        long animTime;
        int fps;
        int tempY = Graphics.getScreenHeight() - 50;        

            
        public void run()
        {
            int count;
            
            //Sleep 50ms to allow the invalidate method in the initialize method to fully execute.
            //This ensures that the screen is fully redrawn in its initial state before
            //this thread starts modifying drawing values, otherwise we'll see frames out of sync.
            try
            {
                sleep(50);
            }
            catch (Exception ex)
            {
                System.out.println("Couldn't sleep!");
            }

            //Get the start time for the animation (FPS timer).
            animTime = rightNow.getTime();
            
            _frameNo = 0;

            UiApplication.getUiApplication().invokeAndWait(new Runnable() {
                public void run() 
                {
                    //We want to clear the entire screen so call invalidate
                    //instead of invalidate(#, #, #, #).
                    invalidate();
                    ++_frameNo;

                }
            });

            //Draw the house with the door open.
            //We don't need to obtain an event lock when using invalidate(#, #, #, #);
            invalidate(170, tempY, 5, 40);

            //Draw the person running out of the house.
            _drawRunner = true;
         
            //If show framerate is enabled calculate and display
            //the freamrate.
            if(SHOW_FRAMERATE)
            {
                //Reset the time.
                rightNow = new Date();
    
                //Calculate the number of seconds the animation animated for.
                //We selpt for 2710 ms so subtract that value from the total time.
                animTime = (rightNow.getTime() - animTime) - 2910;
                
                //Ensure we don't divide by 0.
                if ((animTime / 1000) > 0)
                {
                    //If the animation took longer than a second, calculate it.
                    fps = (int)(_frameNo / (animTime / 1000));
                }
                else
                {
                    //Otherwise assume 1 second.
                    fps = _frameNo;
                }
                
                //Display the frames per second.
                UiApplication.getUiApplication().invokeLater(new Runnable() {
                    public void run() 
                    {
                                                    
                        Dialog.alert("Animation time: " + animTime + " ms.\nAvg FPS: " + fps);
    
                    }
                });
            }
            
            //Animation is over.
            _currentlyAnimating = false;
        }
        
    }

     public static Bitmap rotateImage(Bitmap oldB, int angle) throws Exception
    {
        int w = oldB.getWidth();
        int h = oldB.getHeight();
        
        double angRad = (angle % 360)*(Math.PI/180);
        Bitmap newB = new Bitmap(w,h);
        
        int[] oldD = new int[w*h];
        int[] newD = new int[w*h];
        
        oldB.getARGB(oldD, 0, w, 0, 0, w, h);
        
        int axisX = w/2;
        int axisY = h/2;
        
        for(int x = 0; x < oldD.length; x++)
        {
            int oldX = x%w;
            int oldY = x/w;
            int op = oldX-axisX;
            int adj = oldY-axisY;
            
            double oldT = MathUtilities.atan2(op, adj);
            double rad = Math.sqrt((op*op)+(adj*adj));
            double newT = oldT+angRad;
            
            int newX = (int)MathUtilities.round((rad*Math.sin(newT))+(double)axisX);
            int newY = (int)MathUtilities.round((rad*Math.cos(newT))+(double)axisY);
            
            if(newX<0||newY<0||newX>=w||newY>=h)
            {
                newD[x] = 0x00000000;
            }
            else
            {
                newD[x] = oldD[(newY*w)+newX];
            }
        }
        
        newB.setARGB(newD, 0, w, 0, 0, w, h);
        
        return newB;
    }

    //Let's paint!
    protected void paint(Graphics graphics)
    {

        //Get the screen resolution.
        int width = Graphics.getScreenWidth();
        int height = Graphics.getScreenHeight();
        
        //Counters for the for loops.
        int count, count2;
        
        //Variables to hold temporary x and y values.
        //Storing these in a defined variable is more efficent
        //then calculating them inline as the inline calculation
        //will create a temporary int variable for each calculation.
        //This would result in the creation of a lot of garbage.
        int tempX, tempY;

        if (_drawRunner)
        {
            
            try{
            rotateImage(brick, 59);
        }catch (Exception ex) {
            ex.printStackTrace();
        }
            graphics.drawBitmap(width-30, height-60, 20, 10, brick, 0, 0);
            
        } //end if (_drawRunner)
        
    } //end paint
        
    //Invoked when the trackwheel is clicked.
    public boolean trackwheelClick(int status, int time) 
    {
        boolean retVal = false;
        
        //Only start the animation if one is not in progress.
        if (!_currentlyAnimating)
        {
            _currentlyAnimating = true;
            initialize();
            AnimationThread animationThread = new AnimationThread();
            animationThread.start();
            retVal = true;
        }
        
        return retVal;
    }
    
    //Invoked when the trackwheel is released.
    public boolean trackwheelUnclick(int status, int time) 
    {
        return false;
    }
    
    //Invoked when the trackwheel is rolled.
    public boolean trackwheelRoll(int amount, int status, int time) 
    {
        return false;
    }
    
    //Invoked when a key is pressed.
    public boolean keyChar(char key, int status, int time) 
    {
        boolean retVal = false;
        int tempY = Graphics.getScreenHeight() - 50;
        
        switch (key)
        {
            case Characters.ESCAPE:
                System.exit(0);
                retVal = true;
            break;
            
            case Characters.ENTER:
            case Characters.SPACE:
                //Only start the animation if one is not in progress.
                if (!_currentlyAnimating)
                {
                    _currentlyAnimating = true;
                    initialize();
                    AnimationThread animationThread = new AnimationThread();
                    animationThread.start();
                    retVal = true;
                }
            break;
            
            default:
            break;
        }
                 
        return retVal;
    }

    //Implementation of KeyListener.keyStatus.
    public boolean keyStatus(int keycode, int time) 
    {
       return false;
    }

    //Implementation of KeyListener.keyDown.
    public boolean keyDown(int keycode, int time) 
    {
       return false;
    }
   
    //Implementation of KeyListener.keyRepeat.
    public boolean keyRepeat(int keycode, int time) 
    {
       return false;
    } 
    
    //Implementation of KeyListener.keyUp.
    public boolean keyUp(int keycode, int time) 
    {
       return false;
    }
    
}
This is the other java file:

Code:
package com.msohm.animationDemo;

import net.rim.device.api.ui.*;
import net.rim.device.api.ui.component.*;
import net.rim.device.api.ui.container.*;
import net.rim.device.api.system.*;
import net.rim.device.api.util.*;
import java.util.*;

public class AnimationDemo extends UiApplication
{
    
    //The application enters the event thread by invoking the enterEventDispatcher method.
    public static void main(String[] args)
    {
        AnimationDemo theApp = new AnimationDemo();
        theApp.enterEventDispatcher();
    }

    public AnimationDemo()
    {
        
        AnimationScreen animScreen = new AnimationScreen();
        
        pushScreen(animScreen);
        
    }
    
}
And the png image I attached. Now, in the AnimationScreen.java file you can find the following code:

Code:
public static Bitmap rotateImage(Bitmap oldB, int angle) throws Exception
    {
        int w = oldB.getWidth();
        int h = oldB.getHeight();
        
        double angRad = (angle % 360)*(Math.PI/180);
        Bitmap newB = new Bitmap(w,h);
        
        int[] oldD = new int[w*h];
        int[] newD = new int[w*h];
        
        oldB.getARGB(oldD, 0, w, 0, 0, w, h);
        
        int axisX = w/2;
        int axisY = h/2;
        
        for(int x = 0; x < oldD.length; x++)
        {
            int oldX = x%w;
            int oldY = x/w;
            int op = oldX-axisX;
            int adj = oldY-axisY;
            
            double oldT = MathUtilities.atan2(op, adj);
            double rad = Math.sqrt((op*op)+(adj*adj));
            double newT = oldT+angRad;
            
            int newX = (int)MathUtilities.round((rad*Math.sin(newT))+(double)axisX);
            int newY = (int)MathUtilities.round((rad*Math.cos(newT))+(double)axisY);
            
            if(newX<0||newY<0||newX>=w||newY>=h)
            {
                newD[x] = 0x00000000;
            }
            else
            {
                newD[x] = oldD[(newY*w)+newX];
            }
        }
        
        newB.setARGB(newD, 0, w, 0, 0, w, h);
        
        return newB;
    }
And I am using this method inside the paint method:

Code:
protected void paint(Graphics graphics)
    {

        //Get the screen resolution.
        int width = Graphics.getScreenWidth();
        int height = Graphics.getScreenHeight();
        
        //Counters for the for loops.
        int count, count2;
        
        int tempX, tempY;

        if (_drawRunner)
        {
            
            try{
            rotateImage(brick, 59);
        }catch (Exception ex) {
            ex.printStackTrace();
        }
            graphics.drawBitmap(width-30, height-60, 20, 10, brick, 0, 0);
            
        } //end if (_drawRunner)
        
    } //end paint
The problem is that the brick image is not rotating at a given angle. I hope you understand my question. Let me know please.
Attached Images
File Type: png brick.png (521 Bytes, 20 views)
Offline  




Copyright 2004-2016 BlackBerryForums.com.
The names RIM and BlackBerry are registered Trademarks of BlackBerry Inc.