Skip to main content

ImageView Rotate, Zoom in and out, and Drag on touch

The source code is available at the end of this tutorial


For this Android tutorial, I will show how to create an ImageView which is capable of rotating, pinch zoom in and out and move around on Touch Listener on android devices. 

Here’s a quick and easy guide of Android’s multi-touch feature, i.e., one finger to move, two fingers to pinch zoom in and out and two or three fingers to rotate the ImageView.


Some basics of 2D Matrix transformations knowledge are a requirement for this tutorial. We will use Matrix class to map our points to new points.

 When using Image viewer applications, they usually provide features of image processing, that is, pinch zoom in and zoom out, rotate or drag an image, etc.  This guide takes you through how you can simply implement those features in a few lines of code in Android programmatically.

Note: we will use very few libraries to achieve the same, that is, only for the matrix libraries thus we will use our default Gradle properties configurations unlike other blog posts

First, we need to create our project and then add the java code below to your MainActivity.java and the XML to your activity_main.XML

The entire java code
MainActivity.java 

package com.whatsonline.androidmultitouch;         import android.app.Activity;         import android.graphics.Bitmap;         import android.graphics.Canvas;         import android.graphics.Matrix;         import android.graphics.PointF;         import android.os.Bundle;         import android.view.MotionEvent;         import android.view.View;         import android.view.View.OnTouchListener;         import android.widget.ImageView; public class MainActivity extends Activity implements OnTouchListener {     // these matrices will be used to move and zoom image     private Matrix matrix = new Matrix();     private Matrix savedMatrix = new Matrix();     // we can be in one of these 3 states     private static final int NONE = 0;     private static final int DRAG = 1;     private static final int ZOOM = 2;     private int mode = NONE;     // remember some things for zooming     private PointF start = new PointF();     private PointF mid = new PointF();     private float oldDist = 1f;     private float d = 0f;     private float newRot = 0f;     private float[] lastEvent = null;     private ImageView view, fin;     private  Bitmap bmap;     @Override     public void onCreate(Bundle savedInstanceState) {         super.onCreate(savedInstanceState);         setContentView(R.layout.activity_main);         view = (ImageView) findViewById(R.id.imageView);         fin = (ImageView) findViewById(R.id.imageView1);         view.setOnTouchListener(this);     }     public boolean onTouch(View v, MotionEvent event) {         // handle touch events here         view = (ImageView) v;         switch (event.getAction() & MotionEvent.ACTION_MASK) {             case MotionEvent.ACTION_DOWN:                 savedMatrix.set(matrix);                 start.set(event.getX(), event.getY());                 mode = DRAG;                 lastEvent = null;                 break;             case MotionEvent.ACTION_POINTER_DOWN:                 oldDist = spacing(event);                 if (oldDist > 10f) {                     savedMatrix.set(matrix);                     midPoint(mid, event);                     mode = ZOOM;                 }                 lastEvent = new float[4];                 lastEvent[0] = event.getX(0);                 lastEvent[1] = event.getX(1);                 lastEvent[2] = event.getY(0);                 lastEvent[3] = event.getY(1);                 d = rotation(event);                 break;             case MotionEvent.ACTION_UP:             case MotionEvent.ACTION_POINTER_UP:                 mode = NONE;                 lastEvent = null;                 break;             case MotionEvent.ACTION_MOVE:                 if (mode == DRAG) {                     matrix.set(savedMatrix);                     float dx = event.getX() - start.x;                     float dy = event.getY() - start.y;                     matrix.postTranslate(dx, dy);                 } 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);                     }                     if (lastEvent != null && event.getPointerCount() == 2 || event.getPointerCount() == 3) {                         newRot = rotation(event);                         float r = newRot - d;                         float[] values = new float[9];                         matrix.getValues(values);                         float tx = values[2];                         float ty = values[5];                         float sx = values[0];                         float xc = (view.getWidth() / 2) * sx;                         float yc = (view.getHeight() / 2) * sx;                         matrix.postRotate(r, tx + xc, ty + yc);                     }                 }                 break;            }         view.setImageMatrix(matrix);         bmap= Bitmap.createBitmap(view.getWidth(), view.getHeight(), Bitmap.Config.RGB_565);         Canvas canvas = new Canvas(bmap);         view.draw(canvas);         //fin.setImageBitmap(bmap);         return true;     } public void ButtonClick(View v){     fin.setImageBitmap(bmap); }     /**      * 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);         float s=x * x + y * y;         return (float)Math.sqrt(s);     }     /**      * 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);     }     /**      * Calculate the degree to be rotated by.      *      * @param event      * @return Degrees      */     private float rotation(MotionEvent event) {         double delta_x = (event.getX(0) - event.getX(1));         double delta_y = (event.getY(0) - event.getY(1));         double radians = Math.atan2(delta_y, delta_x);         return (float) Math.toDegrees(radians);     } }

For the Java code, we have added a touch event to our first ImageView to perform all the transformations as shown above. On button click action, set our mapped ImageView to our second ImageView.

The entire XML code
activity_main.XML

<?xml version="1.0" encoding="utf-8"?> <RelativeLayout     android:layout_width="fill_parent"     android:layout_height="fill_parent"     xmlns:android="http://schemas.android.com/apk/res/android" > <FrameLayout     android:layout_width="fill_parent"     android:id="@+id/frm"     android:layout_height="250dp">     <ImageView android:id="@+id/imageView"         android:layout_width="fill_parent"         android:layout_height="250dp"         android:src="@drawable/cat"         android:scaleType="matrix" /> </FrameLayout>     <LinearLayout         android:layout_width="fill_parent"         android:layout_below="@+id/frm"         android:layout_height="match_parent">         <Button             android:layout_width="wrap_content"             android:text="Finalise"             android:onClick="ButtonClick"             android:layout_height="wrap_content" />         <ImageView android:id="@+id/imageView1"             android:layout_width="fill_parent"             android:layout_height="250dp"             android:src="@drawable/cat"             />     </LinearLayout> </RelativeLayout>


For our XML file, we have created two ImageViews and a button widget. The first ImageView will perform the transformations (rotate, zoom, drag). On button click,  our transformed imageView will be set to the second ImageView as Bitmap Image as explained in the Java code below.

public void ButtonClick(View v){     fin.setImageBitmap(bmap); }

The code example below shows how to get a bitmap Image from the transformed ImageView.

 bmap= Bitmap.createBitmap(view.getWidth(), view.getHeight(), Bitmap.Config.RGB_565);   Canvas canvas = new Canvas(bmap);       view.draw(canvas);


Finally, we are done, you can download the code below for a quicker implementation and subscribe to our newsletter to get more of our tutorials direct to your mailbox.


Comments

Popular posts from this blog

web2apk

http://web2apk.com/create.aspx Create App   Intro   About   Changes   MalWare ?   Contact   Privacy Useful Links Bluetooth Mini Keyboards Android Mini PC Reset Android URL App Title Icon or

Android Bar Chart Using MpAndroidChart Library Tutorial

https://www.numetriclabz.com/android-bar-chart-using-mpandroidchart-library-tutorial/ Android Bar Chart Using MpAndroidChart Library Tutorial Objective In this tutorial we learn how to implement Bar Chart using MpAndroidChart Library in your Android App. Download Source Code       Step 1 Contents ·        1  Introduction ·        2  Creating Bar chart o    2.1  Create a new Project o    2.2  Adding library in Project o    2.3  Create Layout o    2.4  To Plot Bar Chart §   2.4.1  Initialize the graph id §   2.4.2  Creating a Dataset §   2.4.3  Defining X-axis labels §   2.4.4  Set the data §   2.4.5  Add the description to the chart §   2.4.6  Run your App § ...

how to retrieve image from sqlite database in android and display in listview

 Android platform provides several ways to store data in our application. 1. SQLite database 2. SharedPreferences etc For our post, we will only work with SQLite database. First and foremost, we need to understand what an SQLite database is? SQLite database  is an open source SQL database that stores data to a text file on a device. It executes SQL Commands to perform a set of functions, that is, create, read, update and delete operations. On my previous post, I showed how to  store data in SQLite database from edit text, retrieve and populate it in a listview . For this post, I will show the SQLite CRUD operations with images from gallery and text from EditText. We need to understand this; images are stored in SQLite database as BLOB data type. A BLOB is a large binary object that can hold a variable amount of data.  Note, we can only store images in the database as BLOB data type. We need to convert our image path to a bitmap th...