Wednesday, December 7, 2011

Android ImageView: Zoom in Zoom out And Drag

Short description about ImageView:
Android supports 3 common image formats PNG, JPG, GIF, along with 9 patch PNG images. Images are stored in the directory res/layout/drawable. 
As of version 1.6 of the Android SDK multiple drawable directories exist for different screen resolutions. There are low, medium, and high DPI specific directories, drawable-ldpi, drawable-mdpi, drawable-hdpi respectively. This allows you to create images at different DPI to enhance the appearance of your application. 
All image filenames should be lowercase and only contain letters, numbers, and underscores.


ImageView displays an arbitrary image, such as an icon. The ImageView class can load images from various sources (such as resources or content providers), takes care of computing its measurement from the image so that it can be used in any layout manager, and provides various display options such as scaling and tinting. 
You can read more about ImageView from here.


Step by Step Image zoom and drag example:
1. Create New Project (for example: touchmv)
2. Add image file (for example "butterfly.png") to "res/drawable/" folder
3. Edit res/layout/main.xml file as following

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
   xmlns:android="http://schemas.android.com/apk/res/android"
   android:id="@+id/root"
   android:layout_width="match_parent"
   android:layout_height="match_parent">

 <ImageView android:id="@+id/imageView"
       android:layout_width="match_parent"
       android:layout_height="match_parent"
       android:src="@drawable/butterfly"
       android:scaleType="matrix"
       android:adjustViewBounds="true"
       android:layout_gravity="center">
    </ImageView>
    
</FrameLayout>
4. Create new class by name "Touch" as following:

package com.blogspot.vmustafayev4en.touchmv.listener;

import android.graphics.Matrix;
import android.graphics.PointF;
import android.util.FloatMath;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.ImageView;

public class Touch implements OnTouchListener {

 // These matrices will be used to move and zoom image
 Matrix matrix = new Matrix();
 Matrix savedMatrix = new Matrix();

 // We can be in one of these 3 states
 static final int NONE = 0;
 static final int DRAG = 1;
 static final int ZOOM = 2;
 int mode = NONE;

 // Remember some things for zooming
 PointF start = new PointF();
 PointF mid = new PointF();
 float oldDist = 1f;

 
 @Override
 public boolean onTouch(View v, MotionEvent event) {
  ImageView view = (ImageView) v;
  // Dump touch event to log
  dumpEvent(event);

  // Handle touch events here...
  switch (event.getAction() & MotionEvent.ACTION_MASK) {
  case MotionEvent.ACTION_DOWN:
   savedMatrix.set(matrix);
   start.set(event.getX(), event.getY());
   mode = DRAG;
   break;
  case MotionEvent.ACTION_POINTER_DOWN:
   oldDist = spacing(event);
   if (oldDist > 10f) {
    savedMatrix.set(matrix);
    midPoint(mid, event);
    mode = ZOOM;
   }
   break;
  case MotionEvent.ACTION_UP:
  case MotionEvent.ACTION_POINTER_UP:
   mode = NONE;
   break;
  case MotionEvent.ACTION_MOVE:
   if (mode == DRAG) {
    // ...    
    matrix.set(savedMatrix);
    matrix.postTranslate(event.getX() - start.x, event.getY() - start.y);    
   } else if (mode == ZOOM) {
    float newDist = spacing(event);
    if (newDist > 10f) {
     matrix.set(savedMatrix);
     float scale = newDist / oldDist;
     matrix.postScale(scale, scale, mid.x, mid.y);
    }
   }
   break;
  }

  view.setImageMatrix(matrix);
  return true; // indicate event was handled
 }

 /** Show an event in the LogCat view, for debugging */
 private void dumpEvent(MotionEvent event) {
  String names[] = { "DOWN", "UP", "MOVE", "CANCEL", "OUTSIDE",
    "POINTER_DOWN", "POINTER_UP", "7?", "8?", "9?" };
  StringBuilder sb = new StringBuilder();
  int action = event.getAction();
  int actionCode = action & MotionEvent.ACTION_MASK;
  sb.append("event ACTION_").append(names[actionCode]);
  if (actionCode == MotionEvent.ACTION_POINTER_DOWN
    || actionCode == MotionEvent.ACTION_POINTER_UP) {
   sb.append("(pid ").append(
     action >> MotionEvent.ACTION_POINTER_ID_SHIFT);
   sb.append(")");
  }
  sb.append("[");
  for (int i = 0; i < event.getPointerCount(); i++) {
   sb.append("#").append(i);
   sb.append("(pid ").append(event.getPointerId(i));
   sb.append(")=").append((int) event.getX(i));
   sb.append(",").append((int) event.getY(i));
   if (i + 1 < event.getPointerCount())
    sb.append(";");
  }
  sb.append("]");
 }

 /** Determine the space between the first two fingers */
 private float spacing(MotionEvent event) {
  float x = event.getX(0) - event.getX(1);
  float y = event.getY(0) - event.getY(1);
  return FloatMath.sqrt(x * x + y * y);
 }

 /** Calculate the mid point of the first two fingers */
 private void midPoint(PointF point, MotionEvent event) {
  float x = event.getX(0) + event.getX(1);
  float y = event.getY(0) + event.getY(1);
  point.set(x / 2, y / 2);
 }
}
5. Change your Activity class as following:

package com.blogspot.vmustafayev4en.touchmv;

import com.blogspot.vmustafayev4en.touchmv.listener.Touch;

import android.app.Activity;
import android.os.Bundle;
import android.widget.ImageView;

public class BlogActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
      ImageView iv = (ImageView) findViewById(R.id.imageView);
      iv.setOnTouchListener(new Touch());
    }
}
If you did all steps then you'll be able to drag image or zoom in zoom out it.

If this post was useful then I am happy and as additional tip would like to share one bestseller course which is great and worst each penny. I strongly recommend to give it a try The Complete Android N Developer Course


This course will teach you an Android App Development while building real apps including Uber, Whatsapp, and Instagram!

Have fun!

68 comments:

  1. This is one of the unique post.This is one of the challenging post.Nice to read about your post.
    Android app developer

    ReplyDelete
  2. This comment has been removed by the author.

    ReplyDelete
  3. The zooming and scrolling goes to infinite. Can we restrict that to some point?

    ReplyDelete
    Replies
    1. I am also facing the same problem. Zooming is going to infinite...how to restrict it.
      Also, I am trying to load the image on the Button Click event. The Touch method is being run but zooming of image is not happening. Please suggest how to implement the same on the button click even in a new screen.

      Delete
    2. use this code

      case MotionEvent.ACTION_MOVE:
      if (mode == DRAG) {
      matrix.set(savedMatrix);
      matrix.postTranslate(event.getX() - start.x, event.getY() - start.y);
      } else if (mode == ZOOM) {
      float[] f = new float[9];
      float newDist = spacing(event);
      if (newDist > 10f) {
      matrix.set(savedMatrix);
      float tScale = newDist / oldDist;
      matrix.postScale(tScale, tScale, mid.x, mid.y);
      }
      matrix.getValues(f);
      float scaleX = f[Matrix.MSCALE_X];
      float scaleY = f[Matrix.MSCALE_Y];
      if (scaleX <= 0.5f) {
      matrix.postScale((0.5f) / scaleX, (0.5f) / scaleY, mid.x, mid.y);
      } else if (scaleX >= 6.0f) {
      matrix.postScale((6.0f) / scaleX, (6.0f) / scaleY, mid.x, mid.y);
      }
      }
      break;

      Delete
    3. thank u very much

      Delete
  4. May I please have the reply...

    ReplyDelete
  5. I have used this code in my android application https://play.google.com/store/apps/details?id=com.blogspot.vmustafayev4en.gdl
    In this program version not enough for u?

    ReplyDelete
  6. This comment has been removed by the author.

    ReplyDelete
  7. This comment has been removed by the author.

    ReplyDelete
  8. I'm wondering how you can limit the zoom. Like Sarma already said, to stop the infinity...also I would like to know how to center the image and zoom in a bit in default.

    ReplyDelete
    Replies
    1. And how do keep the image inside the viewscreen?

      Delete
    2. My Phone is Galaxy S II and android version is 2.3.3, may be why I have normal window in my application

      Delete
  9. can please explain me,how to zoom images in view flipper..??

    ReplyDelete
  10. good work Mr.Vasif, can you explain how this zooming can be implemented with more than 1 image in viewflipper?

    ReplyDelete
  11. These articles have got thorough discernment without unclear the readers.
    root android phone

    ReplyDelete
  12. Excellent, thank you very much, helped me a lot.

    Greetings from Colombia ....

    fanelmar

    ReplyDelete
  13. Thank you for this easy to follow tutorial.

    ReplyDelete
  14. ur post is very usefull thanks....
    have one doubt..can i use two imageviews for drag n zoom in ur coding??

    thanks in advance

    ReplyDelete
  15. Replies
    1. Yaaa..This is Really UseFull Dear....

      Delete
    2. Not at all, please share our official web site with friends www.handysofts.com

      Delete
  16. very nice tutorial!

    thank you very much.

    Hassy

    ReplyDelete
  17. Sorry This is not working, send me full source file on hemant.katariya26@gmail.com

    ReplyDelete
  18. In the code of 5., you should put this code

    iv.setScaleType(ScaleType.MATRIX);

    then it works.

    ReplyDelete
  19. Thanks a lot for gr8 tutorial...

    ReplyDelete
  20. Just Awsmn Work Bro........Was Facing this problem from last many days..Thanks lot

    ReplyDelete
  21. I want to know if it possible to do zoom-in-zoom-out and drag with RelativeLayout???

    ReplyDelete
  22. Really good tutorial...it helped me a lot.
    Can please tell me how to rotate same image??

    ReplyDelete
  23. HI Please check below URL. Need your support.
    I need to create zoom and then able draw on zoom image part . i have done it but when i am saving image when its in zoom i just get image only zoom part which is display in device. Renaming all parts is missing.
    http://stackoverflow.com/questions/26924062/android-zoom-image-and-draw-line-on-image-with-current-zoom

    ReplyDelete
    Replies
    1. HI Please update me if you get something in my question. waiting for your replay.

      Delete
  24. Hi Vasif,
    It's very good one, but how to apply zoom & rotate for multiple images ?

    ReplyDelete
  25. can i integrate with view flipper control??

    ReplyDelete
  26. Replies
    1. Not at all, please share our official web site with friends www.handysofts.com

      Delete
  27. plz tel me how to zoom along x axis and y axis independently????

    ReplyDelete
  28. Replies
    1. Not at all, please share our official web site with friends www.handysofts.com

      Delete
  29. What if i put Linear Layout in place of Frame Layout?
    will it work?

    ReplyDelete
  30. not at all working...!!!!!!!!!!!!

    ReplyDelete
  31. How to make zoom work in scrollview?

    ReplyDelete
  32. I tried most of the sample but in all that image in the imageview is get Zoom-in and Zoom-out..but i got idea over this blogAndroid Training in velachery | Android Training in chennai | Android Training in chennai with placement

    ReplyDelete
  33. private float spacing(MotionEvent event) {
    float x = event.getX(0) - event.getX(1);
    float y = event.getY(0) - event.getY(1);
    return FloatMath.sqrt(x * x + y * y);
    }

    cannot resolve "sqrt"

    ReplyDelete
    Replies
    1. replace with

      private float spacing(MotionEvent event) {
      float x = event.getX(0) - event.getX(1);
      float y = event.getY(0) - event.getY(1);
      return (float) Math.sqrt(x * x + y * y);
      }

      Delete
  34. Good Post! Thank you so much for sharing this pretty post, it was so good to read and useful to improve my knowledge as updated one, keep blogging.
    Click here:
    angularjs training in rajajinagar
    Click here:
    angularjs training in marathahalli

    ReplyDelete
  35. This comment has been removed by the author.

    ReplyDelete
  36. You are doing a great job. I would like to appreciate your work for good accuracy
    Regards,
    Selenium Training Institute in Chennai | Selenium Testing Training in chennai

    ReplyDelete
  37. Thank you for allowing me to read it, welcome to the next in a recent article. And thanks for sharing the nice article, keep posting or updating news article.
    oppo service center chennai
    oppo service center in chennai
    oppo service centre chennai

    ReplyDelete
  38. I am reading your post from the beginning, it was so interesting to read & I feel thanks to you for posting such a good blog, keep updates regularly..
    Android Training Institute in Noida
    Java Training Institute in Noida

    ReplyDelete
  39. Thanks for giving great kind of information. So useful and practical for me. Thanks for your excellent blog, nice work keep it up thanks for sharing the knowledge.
    AWS Training in Chennai | AWS Training Institute in Chennai

    ReplyDelete
  40. Great post. An elegant and an attractive entrance for your homes is now made possible with the help of Elite gates. Choose the Elite gates for your homes and make your investment a smart one which adds more value to your homes. The choice of Elite gates with high safety technology also allows theft free and safety homes for your loved ones at your homes.
    Choose the right brand and enjoy the exiting features and advantages!

    automatic gates

    ReplyDelete
  41. The revolutionary technology of the Nibav Home Lifts has changed the way people and goods are being transported vertically within their homes, and furthermore, has done so in an environmental friendly manner. Rather than using cables or pistons, this unique residential elevator is powered by the most abundant resources in the world ‘AIR’.
    Click here to know more: vacuum elevators India | vacuum lifts

    ReplyDelete
  42. Grab the Oracle Training in Chennai from Infycle Technologies, the best software training and placement center in Chennai which is providing technical software courses such as Data Science, Artificial Intelligence, Cyber Security, Big Data, Java, Hadoop, Selenium, Android, and iOS Development, DevOps, etc with 100% hands-on practical training. Call 7504633633 to get a free demo with more info.

    ReplyDelete
  43. It let you access all the components and programs remotely from anywhere and any device to get full control over the connected system. It is .Download Vnc Server Full Crack

    ReplyDelete