Android app can double click to enlarge and zoom out of the image function _android

Source: Internet
Author: User
Tags gety stub

Let's look at a very simple core image scaling method:

public static Bitmap scale (Bitmap Bitmap, float scalewidth, float scaleheight) { 
  int width = bitmap.getwidth (); 
  int height = bitmap.getheight (); 
  Matrix matrix = new Matrix (); 
  Matrix.postscale (ScaleWidth, scaleheight); 
  LOG.I (TAG, "ScaleWidth:" + ScaleWidth + ", ScaleHeight:" + scaleheight); 
  Return Bitmap.createbitmap (Bitmap, 0, 0, width, height, matrix, True); 
} 

Note that if you want to scale correctly, you may overflow memory, such as when you used picture scaling:

Java.lang.IllegalArgumentException:bitmap size exceeds 32bits

Later a line of code, found that the original is the proportion of scale calculation error, will be magnified to 20 times, resulting in memory overflow, modified proportional value after the normal.

Okay, so here's a real look at this module that enables zooming and scaling up to two levels in the original size.
Features are:

    • Zoom in at the center of the touch point (this is not on the other code on the Web)
    • Border control (this is not the other code on the Web)
    • Double-click to enlarge or shrink (mainly for resistive screen)
    • Multi-point Touch zoom and zoom Out

This module has passed the test, and the user has been used for some time, it is more stable.

The following code and use methods (no write test project, everyone forgive):

ImageControl is similar to a user-defined ImageView control. The usage is posted in the following code.

Import Android.content.Context; 
Import Android.graphics.Bitmap; 
Import Android.graphics.Matrix; 
Import Android.util.AttributeSet; 
Import Android.util.FloatMath; 
Import android.view.MotionEvent; 
 
Import Android.widget.ImageView; 
    public class ImageControl extends ImageView {public ImageControl (context) {super); TODO auto-generated Constructor stub} public ImageControl (context context, AttributeSet Attrs) {Super (CO 
    ntext, attrs);  
    TODO auto-generated Constructor stub} public ImageControl (context, AttributeSet attrs, int defstyle) { 
    Super (context, attrs, Defstyle); 
  TODO auto-generated Constructor stub}//ImageView img; Matrix Imgmatrix = null; Define the transformation matrix of the picture static final int double_click_time_space = 300; Double-click interval static final int double_point_distance = 10; 
  Two point amplification two points between minimum spacing static final int NONE = 0; static final int DRAG = 1; Drag operation static final int ZOOM = 2; Zoom in, zoom in.as private int mode = NONE; Current mode float Bigscale = 3f; Default magnification Boolean Isbig = false; Is the magnification state long lastclicktime = 0; Click Time float startdistance; Multi-point Touch two point distance float enddistance; Multi-point Touch two point distance float topheight; 
 
  Status bar height and title bar height Bitmap primarybitmap = null; float CONTENTW; Screen content area width float contenth; The screen content area height float primaryw; Original artwork width float primaryh; Original height float scale; Suitable for screen scaling multiple Boolean Ismovex = true; Allow Boolean Ismovey = True to be dragged on the x axis; 
  Whether to allow the float startx to be dragged on the Y axis; 
  float Starty; 
  float EndX; 
  float EndY; 
  float SUBX; 
  float Suby; 
  float limitX1; 
  float limitX2; 
  float limitY1; 
  float limitY2; 
 
  Icustommethod mcustommethod = null; 
   /** * Initialization Picture * * @param bitmap * To display the picture * @param contentw * Content Area width * @param contenth * Content Area Height * @param topheight * status bar height and title bar height and/public void Imageinit (Bitmap Bitmap, int conte NTW, int contenth, int topHeight, Icustommethod icustommethod) {this.primarybitmap = bitmap; 
    THIS.CONTENTW = CONTENTW; 
    This.contenth = Contenth; 
    This.topheight = Topheight; 
    Mcustommethod = Icustommethod; 
    Primaryw = Primarybitmap.getwidth (); 
    Primaryh = Primarybitmap.getheight (); 
    float ScaleX = (float) contentw/primaryw; 
    float ScaleY = (float) contenth/primaryh; Scale = ScaleX < ScaleY? 
    Scalex:scaley; 
    if (Scale < 1 && 1/scale < Bigscale) {Bigscale = (float) (1/scale + 0.5); 
    } Imgmatrix = new Matrix (); 
    SUBX = (CONTENTW-PRIMARYW * scale)/2; 
    Suby = (CONTENTH-PRIMARYH * scale)/2; 
    This.setimagebitmap (PRIMARYBITMAP); 
    This.setscaletype (Scaletype.matrix); 
    Imgmatrix.postscale (scale, scale); 
    Imgmatrix.posttranslate (SUBX, Suby); 
  This.setimagematrix (Imgmatrix); /** * Press Operation * @param event/public void MouseDown (Motionevent event) {mode = NONE;
    StartX = Event.getrawx (); 
    Starty = Event.getrawy (); if (event.getpointercount () = = 1) {//If two clicks interval is less than a certain value, the default is to double-click event if (Event.geteventtime ()-Lastclicktime ; 
      Double_click_time_space) {changesize (startx, starty); 
      else if (isbig) {mode = DRAG; 
  } lastclicktime = Event.geteventtime (); /** * Not the first click Operation * * @param event/public void Mousepointdown (Motionevent event) {STARTDI 
    Stance = Getdistance (event); 
    if (Startdistance > double_point_distance) {mode = ZOOM; 
    else {mode = NONE;  }/** * Move operation * * @param event/public void MouseMove (Motionevent event) {if (mode = = 
      DRAG) && (Ismovex | | | ismovey)) {float[] XY = gettranslatexy (Imgmatrix); 
      float TRANSX = 0; 
      float Transy = 0; 
        if (Ismovex) {endx = Event.getrawx (); 
        TRANSX = Endx-startx; if ((xy[0)+ transx) <= limitX1) {transx = limitx1-xy[0]; 
        } if ((xy[0) + transx) >= limitX2) {transx = limitx2-xy[0]; 
        } if (Ismovey) {EndY = Event.getrawy (); 
        Transy = Endy-starty; 
        if ((Xy[1] + transy) <= limitY1) {transy = limity1-xy[1]; 
        } if ((xy[1) + transy) >= limitY2) {transy = limity2-xy[1]; 
      } imgmatrix.posttranslate (TRANSX, Transy); 
      StartX = EndX; 
      Starty = EndY; 
    This.setimagematrix (Imgmatrix); 
      else if (mode = = ZOOM && event.getpointercount () > 1) {enddistance = Getdistance (event); 
      float dif = enddistance-startdistance;  
            if (Math.Abs (enddistance-startdistance) > Double_point_distance) {if (Isbig) {if (dif < 0) { 
            Changesize (0, 0); 
          mode = NONE; 
   } else if (dif > 0) {       float x = event.getx (0)/2 + EVENT.GETX (1)/2; 
          Float y = event.gety (0)/2 + event.gety (1)/2; 
          Changesize (x, y); 
        mode = NONE; 
  /** * Mouse Lift Event/public void MouseUp () {mode = NONE; /** * Image Zoom Zoom Out * * @param x * Click point x Coordinate * @param y * Click Point y-coordinate/private void Cha 
      Ngesize (float x, float y) {if (Isbig) {//If in Maximum state, restore Imgmatrix.reset (); 
      Imgmatrix.postscale (scale, scale); 
      Imgmatrix.posttranslate (SUBX, Suby); 
    Isbig = false; 
      else {Imgmatrix.postscale (Bigscale, Bigscale);///////////////((bigScale-1) * x); float Transy =-((bigScale-1) * (y-topheight)); 
      (bigScale-1) (Y-statusbarheight-suby) +2*suby; float currentwidth = primaryw * scale * bigscale; 
      Enlarged picture size Float Currentheight = primaryh * scale * bigscale; If the picture is enlarged and exceeds the screen range process if (CurreNtheight > Contenth) {limitY1 =-(Currentheight-contenth);//translation restriction limitY2 = 0; Ismovey = true; Allows you to drag a float Currentsuby = Bigscale * Suby on the y axis; 
        After the current translation distance//translation, the upper part of the content area has a blank handling method if (-transy < Currentsuby) {transy =-currentsuby;  if (Currentsuby + Transy < limitY1) {Transy =-(Currentheight +), the lower part of the content area has a blank processing method after translation. 
        Currentsuby-contenth); 
      } else {//If the picture does not exceed the screen scope after zooming in, drag Ismovey = False is not allowed; 
        } if (Currentwidth > contentw) {limitX1 =-(CURRENTWIDTH-CONTENTW); 
        limitX2 = 0; 
        Ismovex = true; 
        float CURRENTSUBX = Bigscale * SUBX; 
        if (-transx < CURRENTSUBX) {transx =-CURRENTSUBX; 
        } if (CURRENTSUBX + TRANSX < limitX1) {TRANSX =-(currentwidth + CURRENTSUBX-CONTENTW); 
      } else {Ismovex = false; 
 }
      Imgmatrix.posttranslate (TRANSX, Transy); 
    Isbig = true; 
    } this.setimagematrix (Imgmatrix); 
    if (Mcustommethod!= null) {Mcustommethod.custommethod (isbig);  }/** * Gets the x-axis offset and y-axis offset of the transformation matrix * * @param matrix * Transformation matrices * @return/private float[] 
    Gettranslatexy (Matrix matrix) {float[] values = new float[9]; 
    Matrix.getvalues (values); 
    float[] floats = new float[2]; 
    Floats[0] = values[matrix.mtrans_x]; 
    FLOATS[1] = values[matrix.mtrans_y]; 
  return floats; 
    /** * Get the distance between two points * * @param event * @return/Private float Getdistance (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); /** * @author Administrator User-defined method */public interface Icustommethod {public void Custommethod (Bo 
  Olean currentstatus); 
 } 
}

Imagevewactivity This activity for testing

Import android.app.Activity; 
Import Android.graphics.Bitmap; 
Import Android.graphics.Rect; 
Import android.graphics.drawable.BitmapDrawable; 
Import Android.os.Bundle; 
Import android.view.MotionEvent; 
Import Android.view.View; 
Import Android.widget.LinearLayout; 
Import Android.widget.TextView; 
Import Android.widget.Toast; 
Import Ejiang.boiler.ImageControl.ICustomMethod; 
 
Import ejiang.boiler.r.id; 
    public class Imageviewactivity extends activity {@Override protected void onCreate (Bundle savedinstancestate) { 
    TODO auto-generated Method Stub super.oncreate (savedinstancestate); 
    Setcontentview (R.layout.common_image_view); 
  Findview (); 
    } public void Onwindowfocuschanged (Boolean hasfocus) {super.onwindowfocuschanged (hasfocus); 
  Init (); 
  } ImageControl Imgcontrol; 
  LinearLayout Lltitle; 
 
  TextView Tvtitle; 
    private void Findview () {Imgcontrol = (ImageControl) Findviewbyid (id.common_imageview_imagecontrol1); LLtitle = (linearlayout) Findviewbyid (id.common_imageview_lltitle); 
  Tvtitle = (TextView) Findviewbyid (id.common_imageview_title); 
    private void Init () {tvtitle.settext ("Picture test"); 
     
    This can be dynamically assigned to the picture path of the Imgcontrol/... 
    Bitmap bmp; 
    if (Imgcontrol.getdrawingcache ()!= null) {BMP = Bitmap.createbitmap (Imgcontrol.getdrawingcache ()); 
    else {bmp = ((bitmapdrawable) imgcontrol.getdrawable ()). Getbitmap (); 
    } Rect frame = new Rect (); 
    GetWindow (). Getdecorview (). Getwindowvisibledisplayframe (frame); 
    int statusbarheight = Frame.top; 
    int screenw = This.getwindowmanager (). Getdefaultdisplay (). GetWidth (); 
    int screenh = This.getwindowmanager (). Getdefaultdisplay (). GetHeight ()-statusbarheight; 
            
            if (BMP!= null) {imgcontrol.imageinit (BMP, Screenw, Screenh, Statusbarheight, New Icustommethod () { @Override public void Custommethod (Boolean cUrrentstatus) {//////When the picture is zoomed in or out, control whether the caption displays if (currentstatus) {Lltitle.setv 
              Isibility (View.gone); 
              else {lltitle.setvisibility (view.visible); 
    } 
            } 
          }); else {toast.maketext (imageviewactivity.this, "Picture load failed, please try again later!") 
    ", Toast.length_short). Show (); @Override public boolean ontouchevent (Motionevent event) {switch (Event.getaction () & Motioneve Nt.       
      Action_mask) {case MotionEvent.ACTION_DOWN:imgControl.mouseDown (event); 
 
    Break 
     
      /** * Not the first point press/Case MotionEvent.ACTION_POINTER_DOWN:imgControl.mousePointDown (event); 
    Break 
       
      Case MotionEvent.ACTION_MOVE:imgControl.mouseMove (event); 
 
    Break 
      Case MotionEvent.ACTION_UP:imgControl.mouseUp (); 
 
    Break Return Super.ontouchevent (Event); 
 } 
}

In the code above, you need to be aware of two points. In an activity, the Ontouchevent method is overridden to pass a touch event to ImageControl, similar to the routed event mechanism in WPF. The second initialization Imgcontrol is the Imgcontrol.imageinit, which takes note of the parameters. The last parameter is similar to a delegate in C #, which I use to implement, and unload this method when I zoom in on a narrowing switch.


Common_image_view.xml Layout file

 <?xml version= "1.0" encoding= "Utf-8"?> <relativelayout "xmlns:android=" /schemas.android.com/apk/res/android "android:id=" @+id/rl "android:layout_width=" Fill_parent "Android:layout_heig" ht= "Fill_parent" > <ejiang.boiler.imagecontrol android:id= "@+id/common_imageview_imagecontrol1" Andro 
 
  Id:layout_width= "Fill_parent" android:layout_height= "fill_parent" android:src= "@drawable/ic_launcher"/> <linearlayout android:id= "@+id/common_imageview_lltitle" style= "@style/reporttitle1" Android:layout_ali Gnparentleft= "true" android:layout_alignparenttop= "true" > <textview android:id= "@+id/common_imag" Eview_title "style=" @style/title2 "android:layout_width=" fill_parent "android:layout_height=" Wrap_con 

Tent "android:layout_weight=" 1 "android:text=" Report "/> </LinearLayout> </RelativeLayout> 

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.