Enlarge and drag Bitmap in custom View in Android

Source: Internet
Author: User

Enlarge and drag Bitmap in custom View in Android
In Android, enable Bitmap to zoom in and drag in the Custom View. 1. The basic implementation idea is to implement the custom View-MyImageView Class Based on The View class. Complete the OnTouchListener interface in the Activity class of View, this allows you to monitor, zoom, and drag touch events of custom views. The Bitmap object is dragged on the View and the View edge is detected to prevent the drag from passing through the border. The Bitmap object is amplified on The View Based on Two-point touch, and the magnification is detected. Based on the Matrix object, Bitmap can be zoomed in and translated on the View. Bitmap objects are updated and displayed in the View. By reloading the onDraw method, the Bitmap object is drawn using canvas, and the view is used. the invalidate () method refreshes the View. Description of important methods of the MyImageView class: initParameters () initializes all the required parameters setStartPoint () set the start point coordinate of image translation setMovePoint () set the Moving Point Coordinate of image translation, then, calculate the distance between them at the starting point of the set to obtain the two parameter values sx and sy to be translated by the Bitmap object. This also includes the check code that ensures that the image does not cross the View boundary. SavePreviousResult () saves the current Translation Data. Next time, you can continue to translate Bitmap Objects Based on the next translation. ZoomIn () obtains the amplification ratio based on the Euclidean distance between two points through the initial distance comparison, and implements Bitmap's amplification Matrix on the View object. postScale method and Matrix. the postTranslate method can achieve translation and amplification without changing the Bitmap object itself. OnTouchListener supports the following touch event processing: ACTION_DOWN event, recording the ACTION_UP event at the start of the translation, ending the translation event to process the ACTION_MOVE event, recording the translation point, calculating the distance from the start point, and realizing Bitmap translation, in multi-touch mode, the distance between two points is calculated to enlarge the ACTION_POINTER_DOWN event of the image, and the distance between two points is calculated as the initial distance, which is used for image gesture amplification. ACTION_POINTER_UP event, end two-point touch zoom Image Processing 2: code to implement custom View in layout using xml as follows:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:paddingBottom="@dimen/activity_vertical_margin"    android:paddingLeft="@dimen/activity_horizontal_margin"    android:paddingRight="@dimen/activity_horizontal_margin"    android:paddingTop="@dimen/activity_vertical_margin"    tools:context=".MainActivity" >    <com.example.matrixdemo.MyImageView        android:id="@+id/myView"        android:layout_width="fill_parent"        android:layout_height="fill_parent"        android:text="@string/hello_world" /></RelativeLayout>

 

The implementation code of the custom View class is as follows:
Package com. example. matrixdemo; import android. content. context; import android. graphics. bitmap; import android. graphics. canvas; import android. graphics. color; import android. graphics. matrix; import android. graphics. paint; import android. graphics. paint. style; import android. graphics. point; import android. graphics. rect; import android. util. attributeSet; import android. view. view; public class MyImageView extends View {private Paint mPaint; private Bitmap bitmap; private Matrix matrix; // Translation Start Point and Moving Point private Point startPoint; private Point movePoint; private float initDistance; // record the current translation distance: private int sx; private int sy; // Save the translation status: private int oldsx; private int oldsy; // scale rate private float widthRate; private float heightRate; public MyImageView (Context context) {super (context);} public MyImageView (C Ontext context, AttributeSet attrs) {super (context, attrs);} public void setBitmap (Bitmap bitmap) {this. bitmap = bitmap;} private void initParameters () {// initialize the Paint brush mPaint = new Paint (); mPaint. setColor (Color. BLACK); matrix = new Matrix (); if (bitmap! = Null) {float iw = bitmap. getWidth (); float ih = bitmap. getHeight (); float width = this. getWidth (); float height = this. getHeight (); // initial shrinkage ratio widthRate = width/iw; heightRate = height/ih;} sx = 0; sy = 0; oldsx = 0; oldsy = 0 ;} public void setStartPoint (Point startPoint) {this. startPoint = startPoint;} public void setInitDistance (float initDistance) {this. initDistance = initDistance ;} Public void zoomIn (float distance) {float rate = distance/this. initDistance; float iw = bitmap. getWidth (); float ih = bitmap. getHeight (); float width = this. getWidth (); float height = this. getHeight (); // get scale rate widthRate = (width/iw) * rate; heightRate = (height/ih) * rate; // make it same as view size float iwr = (width/iw); float ihr = (height/ih); if (iwr> = widthRate) {wi DthRate = (width/iw);} if (ihr> = heightRate) {heightRate = (height/ih);} // go to center oldsx = (int) (width-widthRate * iw)/2); oldsy = (int) (height-heightRate * ih)/2);} public void setMovePoint (Point movePoint) {this. movePoint = movePoint; sx = this. movePoint. x-this. startPoint. x; sy = this. movePoint. y-this. startPoint. y; float iw = bitmap. getWidth (); float ih = bitmap. get Height (); // Edge Detection int deltax = (int) (widthRate * iw)-this. getWidth (); int deltay = (int) (heightRate * ih)-this. getHeight (); if (sx + this. oldsx)> = 0) {this. oldsx = 0; sx = 0;} else if (sx + this. oldsx) <=-deltax) {this. oldsx =-deltax; sx = 0;} if (sy + this. oldsy)> = 0) {this. oldsy = 0; this. sy = 0;} else if (sy + this. oldsy) <=-deltay) {this. oldsy =-deltay; this. sy = 0;} floa T width = this. getWidth (); // initial shrinkage ratio float iwr = width/iw; if (iwr = widthRate) {sx = 0; sy = 0; oldsx = 0; oldsy = 0 ;}} public void savePreviousResult () {this. oldsx = this. sx + this. oldsx; this. oldsy = this. sy + this. oldsy; // zero sx = 0; sy = 0 ;}@ Override protected void onDraw (Canvas canvas) {if (matrix = null) {initParameters ();} if (bitmap! = Null) {matrix. reset (); matrix. postScale (widthRate, heightRate); matrix. postTranslate (oldsx + sx, oldsy + sy); canvas. drawBitmap (bitmap, matrix, mPaint);} else {// fill rect Rect rect = new Rect (0, 0, getWidth (), getHeight (); mPaint. setAntiAlias (true); mPaint. setColor (Color. BLACK); mPaint. setStyle (Style. FILL_AND_STROKE); canvas. drawRect (rect, mPaint );}}}

 

The MainActivity code is as follows:
package com.example.matrixdemo;import android.app.Activity;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.Point;import android.os.Bundle;import android.util.Log;import android.view.Menu;import android.view.MotionEvent;import android.view.View;import android.view.View.OnTouchListener;public class MainActivity extends Activity implements OnTouchListener {    public static final int SCALE_MODE = 4;    public static final int TRANSLATION_MODE = 2;    public static final int NULL_MODE = 1;    private MyImageView myView;    private int mode;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        startMyImageView();    }    private void startMyImageView() {        myView = (MyImageView) this.findViewById(R.id.myView);        Bitmap bitmap = BitmapFactory.decodeResource(this.getResources(),                R.drawable.flower_001);        myView.setBitmap(bitmap);        myView.setOnTouchListener(this);        myView.invalidate();    }    @Override    public boolean onCreateOptionsMenu(Menu menu) {        getMenuInflater().inflate(R.menu.main, menu);        return true;    }    @Override    public boolean onTouch(View view, MotionEvent event) {        Log.i("touch event","touch x = " + event.getX());        switch (MotionEvent.ACTION_MASK & event.getAction())         {            case MotionEvent.ACTION_DOWN:                mode = TRANSLATION_MODE;                myView.setStartPoint(new Point((int)event.getX(), (int)event.getY()));                break;            case MotionEvent.ACTION_POINTER_UP:            case MotionEvent.ACTION_OUTSIDE:            case MotionEvent.ACTION_UP:                mode = NULL_MODE;                myView.savePreviousResult();                break;            case MotionEvent.ACTION_POINTER_DOWN:                mode = SCALE_MODE;                myView.setInitDistance(calculateDistance(event));                break;            case MotionEvent.ACTION_MOVE:                if(mode == SCALE_MODE)                {                    float dis = calculateDistance(event);                    myView.zoomIn(dis);                }                else if(mode == TRANSLATION_MODE)                {                    myView.setMovePoint(new Point((int)event.getX(), (int)event.getY()));                }                else                {                    Log.i("unknow mode tag","do nothing......");                }                break;        }        myView.invalidate();        return true;    }    private float calculateDistance(MotionEvent event) {        float dx = event.getX(0) - event.getX(1);        float dy = event.getY(0)  - event.getY(1);        float distance = (float)Math.sqrt(dx*dx + dy*dy);        return distance;    }}

 


Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.