views:

142

answers:

4

Hi, I'm trying to draw an image in a view but having problems trying to maintain the scale of the original image. Basically, I have a small view and I would like to show part of the image in the view. The intention then is to perform a translation on the image so that a different part appears in the view.

No matter what I try, either the image is down-scaled automatically to fit the view or the whole image is viewable. I've tried playing about with the settings on BitmapDrawable, ImageView and Layout to no avail.

Anyone know a good way to achieve this?

A: 

This probably won't be the most efficient way, but if you're not going to be moving it too much, it'll do. Treat it like a spritesheet, use Bitmap.createBitmap(Bitmap source, int x, int y, int width, int height) to get the section you want from the original bitmap as its own bitmap, then pass that in instead. Then pass that in rather than the whole bitmap, and it'll only be working with the part you want it to show.

AaronM
A: 

Thanks for the suggestion AaronM, but I don't think this will suit my purpose. What I was looking to do was to create a smooth animation with the image scrolling up or down, depending on the touch gesture so that it looks like a numbered spinner - like setting the clock in the Android alarm app. I can do it by drawing the sequence of numbers but the animation is a bit jerky and I was hoping to achive the smooth animation which is evident in the alarm app. Thanks.

John J Smith
this should be a comment
Janusz
Sorry Janusz - didn't know how to till now :-)
John J Smith
More stuff I've read seems to indicate that the use of SurfaceView might provide more control over graphics and animation. I've just tried it but writing text to the SurfaceView looks horrible!
John J Smith
Praveen - I've just tried this and it definitely has potential. Thanks for the code.
John J Smith
A: 

Sounds like you want to have a big ImageView control inside a smaller View (acting like a window), and then move the ImageView control around inside that, so only part of it is visible at a time.

Not exactly sure how you'd do that though, but pretty sure it's possible with AbsoluteLayout and a bit of tinkering.

Dave
+1  A: 

Hope This piece of code helps. I have googled it a month ago. It Scrolling performance for the Larger Images.Here whole display size is set as the Height and width of the view. You can change you know. and also can maintain the zoom controls too.

public class LargeImageScroller extends Activity {

// Physical display width and height.
private static int displayWidth = 0;
private static int displayHeight = 0;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
     super.onCreate(savedInstanceState);

     // displayWidth and displayHeight will change depending on screen
     // orientation. To get these dynamically, we should hook onSizeChanged().
     // This simple example uses only landscape mode, so it's ok to get them
     // once on startup and use those values throughout.
     Display display = ((WindowManager)
          getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
     displayWidth = display.getWidth();
     displayHeight = display.getHeight();

     // SampleView constructor must be constructed last as it needs the
     // displayWidth and displayHeight we just got.
     setContentView(new SampleView(this));
}

private static class SampleView extends View {
     private static Bitmap bmLargeImage; //bitmap large enough to be scrolled
     private static Rect displayRect = null; //rect we display to
     private Rect scrollRect = null; //rect we scroll over our bitmap with
     private int scrollRectX = 0; //current left location of scroll rect
     private int scrollRectY = 0; //current top location of scroll rect
     private float scrollByX = 0; //x amount to scroll by
     private float scrollByY = 0; //y amount to scroll by
     private float startX = 0; //track x from one ACTION_MOVE to the next
     private float startY = 0; //track y from one ACTION_MOVE to the next

     public SampleView(Context context) {
          super(context);

          // Destination rect for our main canvas draw. It never changes.
          displayRect = new Rect(0, 0, displayWidth, displayHeight);
          // Scroll rect: this will be used to 'scroll around' over the
          // bitmap in memory. Initialize as above.
          scrollRect = new Rect(0, 0, displayWidth, displayHeight);

          // Load a large bitmap into an offscreen area of memory.
          bmLargeImage = BitmapFactory.decodeResource(getResources(),
               R.drawable.testlargeimage);
     }

     @Override
     public boolean onTouchEvent(MotionEvent event) {

          switch (event.getAction()) {
               case MotionEvent.ACTION_DOWN:
                    // Remember our initial down event location.
                    startX = event.getRawX();
                    startY = event.getRawY();
                    break;

               case MotionEvent.ACTION_MOVE:
                    float x = event.getRawX();
                    float y = event.getRawY();
                    // Calculate move update. This will happen many times
                    // during the course of a single movement gesture.
                    scrollByX = x - startX; //move update x increment
                    scrollByY = y - startY; //move update y increment
                    startX = x; //reset initial values to latest
                    startY = y;
                    invalidate(); //force a redraw
                    break;
          }
          return true; //done with this event so consume it
     }

     @Override
     protected void onDraw(Canvas canvas) {

          // Our move updates are calculated in ACTION_MOVE in the opposite direction
          // from how we want to move the scroll rect. Think of this as dragging to
          // the left being the same as sliding the scroll rect to the right.
          int newScrollRectX = scrollRectX - (int)scrollByX;
          int newScrollRectY = scrollRectY - (int)scrollByY;

          // Don't scroll off the left or right edges of the bitmap.
          if (newScrollRectX < 0)
               newScrollRectX = 0;
          else if (newScrollRectX > (bmLargeImage.getWidth() - displayWidth))
               newScrollRectX = (bmLargeImage.getWidth() - displayWidth);

          // Don't scroll off the top or bottom edges of the bitmap.
          if (newScrollRectY < 0)
               newScrollRectY = 0;
          else if (newScrollRectY > (bmLargeImage.getHeight() - displayHeight))
               newScrollRectY = (bmLargeImage.getHeight() - displayHeight);

          // We have our updated scroll rect coordinates, set them and draw.
          scrollRect.set(newScrollRectX, newScrollRectY,
               newScrollRectX + displayWidth, newScrollRectY + displayHeight);
          Paint paint = new Paint();
          canvas.drawBitmap(bmLargeImage, scrollRect, displayRect, paint);

          // Reset current scroll coordinates to reflect the latest updates,
          // so we can repeat this update process.
          scrollRectX = newScrollRectX;
          scrollRectY = newScrollRectY;

     }
}
}
Praveen Chandrasekaran