Android to cut image code sharing at any rate _android

Source: Internet
Author: User
Tags pow

A small partner of the company writes that the picture can be cropped at any rate. I think it's very useful. Simply record it here and it will definitely be used later.

public class Seniorcropimageview extends ImageView implements Scalegesturedetector.onscalegesturelistener, 
View.onlayoutchangelistener {/* For drawing Color field start/private static final int line_color = Color.White; 
private static final int outer_mask_color = COLOR.ARGB (191, 0, 0, 0); 
private static final int line_width_in_dp = 1; 
Private final float[] mmatrixvalues = new FLOAT[9]; 
protected Matrix Msupportmatrix; 
protected Scalegesturedetector Mscalegesturedetector; 
/* For drawing Color Field end */protected Paint mpaint; 
/* * wide ratio/protected float mratio = 1.0f; 
protected RECTF Mcroprect; 
Rectfpadding is to adapt to product requirements, to the crop box mcroprect set padding-chenglin April 18, 2016 protected float rectfpadding = 0; 
protected int mlastx; 
protected int mlasty; 
protected OPERATION moperation; 
Private Onbitmaploadlistener ibitmaploading = null; 
Private Boolean menabledrawcropwidget = true; 
/* For scale and drag * * Private Matrix Mbasematrix; 
Private Matrix Mdrawmatrix; Private acceleratedecelerateinterpolator sinterpolator = new Acceleratedecelerateinterpolator (); 
Private Path MPath; 
private int mlinewidth; 
private float Mscalemax = 3.0f; 
Private RECTF Mboundaryrect; 
private int mrotation = 0; 
private int mimagewidth; 
private int mimageheight; 
private int mdisplayw; 
private int mdisplayh; 
Public Seniorcropimageview {This (context, NULL); 
Public Seniorcropimageview (context, AttributeSet attrs) {This (context, attrs, 0); Seniorcropimageview (context, AttributeSet attrs, int defstyleattr) {Super (context, Attrs, defstyleattr 
); 
if (attrs!= null) {TypedArray a = Context.obtainstyledattributes (Attrs, r.styleable.life_cropimage); 
Mratio = A.getfloat (R.styleable.life_cropimage_life_crop_ratio, 1.0f); 
A.recycle (); 
Init (); public static void Decodeimageforcropping (final String path, final Idecodecallback callback) {New Thread (new Runnable () {@Override public void run () {int rotation= 0; 
Read the rotation try {exifinterface exif = new Exifinterface (path) in EXIF; 
final int rotate = Exif.getattributeint (exifinterface.tag_orientation, exifinterface.orientation_undefined); 
Switch (rotate) {case ExifInterface.ORIENTATION_ROTATE_90:rotation = 90; 
Break 
Case ExifInterface.ORIENTATION_ROTATE_180:rotation = 180; 
Break 
Case ExifInterface.ORIENTATION_ROTATE_270:rotation = 270; 
Break 
} catch (IOException e) {e.printstacktrace (); 
Final Bitmapfactory.options Options = new Bitmapfactory.options (); 
Options.injustdecodebounds = true; 
Bitmapfactory.decodefile (path, options); 
Final int texturelimit = Getmaxtexturesize (); 
int scale = 1; 
while (Options.outwidth/scale >= texturelimit) {scale *= 2; 
while (Options.outheight/scale >= texturelimit) {scale *= 2; 
} options.insamplesize = scale; 
Options.injustdecodebounds = false; 
Bitmap Bitmap = null; 
try {bitmap = bitmapfactory.decodefile (path, options); catch (OutOfMemoryError E) {e.printstacktrace (); 
Final Bitmap bimapdecoded = Bitmap; 
if (bimapdecoded = = null) {return; 
} if (callback!= null) {callback.ondecoded (rotation, bimapdecoded); 
}}). Start (); 
private static int getmaxtexturesize () {EGL10 EGL = (EGL10) Eglcontext.getegl (); Egldisplay display = Egl.eglgetdisplay (EGL10. 
Egl_default_display); 
Initialise int[] Version = new INT[2]; 
Egl.eglinitialize (display, version); 
Query total number of configurations int[] totalconfigurations = new Int[1]; 
Egl.eglgetconfigs (display, NULL, 0, totalconfigurations); 
Query actual list configurations eglconfig[] configurationslist = new Eglconfig[totalconfigurations[0]]; 
Egl.eglgetconfigs (Display, configurationslist, totalconfigurations[0], totalconfigurations); 
int[] texturesize = new Int[1]; 
int maximumtexturesize = 0; Iterate through the configurations to located the maximum size for (int i = 0; i < texture 0]; i++) {//need to check for Width since OpenGL textures are always squared egl.eglgetconfigattrib (display, configurationslist[i], EGL10. 
Egl_max_pbuffer_width, texturesize); Keep track of the maximum texture size if (Maximumtexturesize < texturesize[0]) {maximumtexturesize = Texturesize 
[0]; 
}//Release egl.eglterminate (display); 
return maximumtexturesize; @Override public void Onlayoutchange (View v., int left, int. top, int right, int bottom, int oldleft, int oldtop, int ol 
dright, int oldbottom) {mdisplayw = Right-left; 
Mdisplayh = Bottom-top; if (getdrawable ()!= null && (bitmapdrawable) getdrawable ()). Getbitmap ()!= null) {calculateproperties ((Bitma 
pdrawable) getdrawable ()). Getbitmap ()); 
} private void Init () {mscalegesturedetector = new Scalegesturedetector (GetContext (), this); 
Mbasematrix = new Matrix (); 
Mdrawmatrix = new Matrix (); 
Msupportmatrix = new Matrix (); 
Mlinewidth = (int) diptopixels (LINE_WIDTH_IN_DP); 
Mpaint = new Paint (); Represents the first solid segment length DashonwidtH, the first virtual segment length dashoffwidth MPath = new Path (); 
Mcroprect = new RECTF (); 
Mboundaryrect = new RECTF (); 
Setscaletype (Scaletype.matrix); 
Setclickable (TRUE); Private float diptopixels (float dip) {return typedvalue.applydimension (Typedvalue.complex_unit_dip, Dip, GetResource 
S (). Getdisplaymetrics ()); 
} @Override protected void Onattachedtowindow () {Super.onattachedtowindow (); 
Addonlayoutchangelistener (this); 
} @Override protected void Ondetachedfromwindow () {Super.ondetachedfromwindow (); 
Removeonlayoutchangelistener (this); /** * Sets the cropping ratio of the picture, such as 3:4 0.75 * * @param ratio/public void setcropratio (final float ratio) {if (Mratio = = ratio 
) {return; 
} mratio = ratio; 
After selecting the proportions, restore the rotation angle//setimagerotation (0); 
if (getdrawable () = = null) {return; 
} calculateproperties ((bitmapdrawable) getdrawable ()). Getbitmap ()); 
Postinvalidate (); 
public void setimagerotation (int rotation) {if (mrotation = = rotation) {return; 
} mrotation = rotation; if (Getdrawable () = = null) {return; 
} calculateproperties ((bitmapdrawable) getdrawable ()). Getbitmap ()); 
Postinvalidate (); 
public void setcroprectpadding (float padding) {rectfpadding = padding; 
public void setImagePath (final String path) {if (Textutils.isempty (path)) {return; 
} if (ibitmaploading!= null) {Ibitmaploading.onloadprepare ();  Decodeimageforcropping (Path, new Idecodecallback () {@Override public void ondecoded (final int rotation, final Bitmap 
Bitmap) {post (new Runnable () {@Override public void run () {mrotation = rotation; 
Setimagebitmap (bitmap); 
if (ibitmaploading!= null) {ibitmaploading.onloadfinish (); 
} 
} 
}); 
} 
}); 
@Override public void Setimagebitmap (Bitmap bm) {calculateproperties (BM); 
Super.setimagebitmap (BM); 
public void Setbitmaploadinglistener (Onbitmaploadlistener ibitmapload) {ibitmaploading = Ibitmapload; 
} protected void Calculateproperties (Bitmap bm) {msupportmatrix.reset (); 
Mbasematrix.reset (); int widthsize = MDiSplayw; 
int heightsize = Mdisplayh; 
Generatecroprect (Widthsize, heightsize); 
Mimagewidth = Bm.getwidth (); 
Mimageheight = Bm.getheight (); 
Final Boolean rotated = isimagerotated (); Final int bitmapwidth = rotated? 
Mimageheight:mimagewidth; Final int bitmapheight = rotated? 
Mimagewidth:mimageheight; 
Mboundaryrect.set (0, 0, bitmapwidth, bitmapheight); 
Final float Widthscale = mcroprect.width ()/bitmapwidth; 
Final float Heightscale = mcroprect.height ()/bitmapheight; 
Final float scale = Math.max (Widthscale, Heightscale); 
Final float scaledheight = scale * bitmapheight; 
Final float scaledwidth = scale * BITMAPWIDTH; 
Move to the center point final int translatex = (int) (Mcroprect.left + mcroprect.width ()/2-SCALEDWIDTH/2); 
Final int translatey = (int) (Mcroprect.top + mcroprect.height ()/2-SCALEDHEIGHT/2); 
Mbasematrix.setscale (scale, scale); 
Mbasematrix.posttranslate (Translatex, Translatey); 
Mbasematrix.maprect (Mboundaryrect); 
Setimagematrix (Getdrawmatrix ()); } PrivaTe boolean isimagerotated () {return (mrotation% 360) = = 90) | | 
((mrotation% 360) = = 270); } private void Generatecroprect (int boundarywidth, int boundaryheight) {//rectfpadding is adapted to product requirements, 
Set the clipping box mcroprect padding-chenglin April 18, 2016 boundarywidth = boundarywidth-(int) (rectfpadding * 2); 
Boundaryheight = boundaryheight-(int) (rectfpadding * 2); 
int left; 
int top; 
int right; 
int bottom; 
Boolean vertical; 
Width/height in proportion, the description of the cropping box is "vertical" vertical = (float) boundarywidth/boundaryheight > mratio; 
Final int recth = (int) (boundarywidth/mratio); 
Final int rectw = (int) (boundaryheight * mratio); 
if (vertical) {left = (BOUNDARYWIDTH-RECTW)/2; 
top = 0; 
right = (boundarywidth + rectw)/2; 
bottom = Boundaryheight; 
else {left = 0; 
top = (BOUNDARYHEIGHT-RECTH)/2; 
right = Boundarywidth; 
Bottom = (boundaryheight + recth)/2; //rectfpadding is to adapt to product requirements, to the crop box mcroprect set padding-chenglin April 18, 2016 Mcroprect.set (left + rectfpadding, top + RECTFP adding,Right + rectfpadding, bottom + rectfpadding); 
} @Override protected void OnDraw (Canvas Canvas) {Super.ondraw (Canvas); 
if (!menabledrawcropwidget) {return; 
} if (getdrawable () = = null) {return; 
} mpaint.reset (); 
Mpaint.setantialias (TRUE); 
Mpaint.setcolor (Line_color); 
Mpaint.setstrokewidth (Mlinewidth); 
Mpaint.setstyle (Paint.Style.STROKE); 
Mpath.reset (); 
Upper Mpath.moveto (Mcroprect.left, mcroprect.top); 
Mpath.lineto (Mcroprect.right, mcroprect.top); 
Left Mpath.moveto (Mcroprect.left, mcroprect.top); 
Mpath.lineto (Mcroprect.left, Mcroprect.bottom); 
Right Mpath.moveto (mcroprect.right, mcroprect.top); 
Mpath.lineto (Mcroprect.right, Mcroprect.bottom); 
Lower Mpath.moveto (Mcroprect.right, Mcroprect.bottom); 
Mpath.lineto (Mcroprect.left, Mcroprect.bottom); 
Canvas.drawpath (MPath, mpaint); 
Draw the outer shadow part Mpaint.reset (); 
Mpaint.setantialias (TRUE); 
Mpaint.setcolor (Color.parsecolor ("#B3333333")); 
Mpaint.setstyle (Paint.Style.FILL); The following four rectangles are decorative, which is the four shadows around the clipping box final int LinEoffset = Mlinewidth; 
if (Mcroprect.top > 0) {canvas.drawrect (0, 0, getmeasuredwidth (), Mcroprect.top-lineoffset, mpaint); } if (Mcroprect.left > 0) {canvas.drawrect (mcroprect.top-lineoffset-rectfpadding, Rectfpadding-lineoffset, MCr 
Oprect.left-lineoffset, Mcroprect.bottom + Lineoffset, mpaint); } if (Mcroprect.right < Getmeasuredwidth ()) {Canvas.drawrect (mcroprect.right + lineoffset, MCROPRECT.TOP-LINEOFFSE 
T, Getmeasuredwidth (), Mcroprect.bottom + Lineoffset, mpaint);  } if (Mcroprect.bottom < Getmeasuredheight ()) {canvas.drawrect (0, Mcroprect.bottom + lineoffset, Getmeasuredwidth (), 
Getmeasuredheight (), mpaint); } public boolean ontouchevent (motionevent ev) {if (Ev.getpointercount () > 1) {moperation = OPERATION. 
SCALE; 
return mscalegesturedetector.ontouchevent (EV); 
Final int action = ev.getactionmasked (); 
Final int x = (int) ev.getx (); 
Final int y = (int) ev.gety (); Switch (action) {Case MotionEvent.ACTION_DOWN:mOperation = OPERATION. 
DRAG; 
MLASTX = x; 
Mlasty = y; 
Break Case MotionEvent.ACTION_MOVE:if (moperation = = OPERATION. 
DRAG) {int deltax = X-MLASTX; 
int deltay = Y-mlasty; 
RECTF boundary = Getdrawboundary (Getdrawmatrix ()); 
if (Boundary.left + deltax > Mcroprect.left) {deltax = (int) (mcroprect.left-boundary.left); 
else if (boundary.right + DeltaX < mcroprect.right) {deltax = (int) (mcroprect.right-boundary.right); 
} if (Boundary.top + DeltaY > mcroprect.top) {deltay = (int) (mcroprect.top-boundary.top); 
else if (Boundary.bottom + DeltaY < mcroprect.bottom) {DeltaY = (int) (mcroprect.bottom-boundary.bottom); 
} msupportmatrix.posttranslate (DeltaX, DeltaY); 
Setimagematrix (Getdrawmatrix ()); 
MLASTX = x; 
Mlasty = y; 
} break; 
Case MotionEvent.ACTION_CANCEL:case MotionEvent.ACTION_POINTER_UP:case MotionEvent.ACTION_UP:mLastX = 0; 
mlasty = 0; 
Moperation = null; 
Break 
return super.ontouchevent (EV); 
Public Bitmap Getoriginbitmap () {Bitmapdrawable drawable = (bitmapdrawable) getdrawable (); return drawable = null? 
Null:drawable.getBitmap (); 
/** * Save Picture as Bitmap/public Bitmap Savecrop () throws OutOfMemoryError {if (getdrawable () = null) {return null; 
} Bitmap origin = Getoriginbitmap (); 
Matrix Drawmatrix = Getdrawmatrix (); 
Reverse the matrix matrices inverse = the new matrix (); 
Drawmatrix.invert (inverse); 
The cropping box corresponds to the original image up RECTF cropmapped = new RECTF (); 
Inverse.maprect (cropmapped, mcroprect); 
Clampcroprect (cropmapped, Origin.getwidth (), Origin.getheight ()); 
If a rotation is generated, a rotation matrix rotationm = new Matrix () is required. 
if (mrotation% 360!= 0) {rotationm.postrotate (mrotation, Origin.getwidth ()/2, Origin.getheight ()/2); } Bitmap cropped = Bitmap.createbitmap (origin, (int) cropmapped.left, (int) cropmapped.top, (int) cropmapped.width (), ( 
int) cropmapped.height (), rotationm, true); 
return cropped; } private void Clampcroprect (RECTF croprect, int borderw, int borderh) {if (Croprect.left < 0) {CRoprect.left = 0; 
} if (Croprect.top < 0) {croprect.top = 0; 
} if (Croprect.right > Borderw) {croprect.right = Borderw; 
} if (Croprect.bottom > Borderh) {croprect.bottom = Borderh; 
@Override public boolean Onscale (Scalegesturedetector detector) {Float scale = detector.getscalefactor (); 
if (scale = = 1.0f) {return true; 
Final float Currentscale = Getscale (Msupportmatrix); 
Final float CenterX = Detector.getfocusx (); 
Final float centery = Detector.getfocusy (); if (Currentscale <= 1.0f && Scale < 1.0f) | | (Currentscale >= mscalemax && scale > 1.0f)) 
{return true; 
} if (Currentscale * Scale < 1.0f) {scale = 1.0f/currentscale; 
else if (Currentscale * scale > Mscalemax) {scale = Mscalemax/currentscale; 
} msupportmatrix.postscale (scale, scale, CenterX, centery); 
RECTF boundary = Getdrawboundary (Getdrawmatrix ()); 
float Translatex = 0; if (Boundary.left > Mcroprect.left) {Translatex = MCROPRECT.LEft-boundary.left; 
else if (Boundary.right < mcroprect.right) {Translatex = Mcroprect.right-boundary.right; 
} log.d ("scale", "x==>" + Translatex); 
float Translatey = 0; 
if (Boundary.top > Mcroprect.top) {translatey = Mcroprect.top-boundary.top; 
else if (Boundary.bottom < mcroprect.bottom) {Translatey = Mcroprect.bottom-boundary.bottom; 
} msupportmatrix.posttranslate (Translatex, Translatey); 
Setimagematrix (Getdrawmatrix ()); 
return true; 
} protected Matrix Getdrawmatrix () {mdrawmatrix.reset (); 
if (mrotation% 360!= 0) {Final Boolean rotated = isimagerotated (); Final int width = rotated? 
Mimageheight:mimagewidth; Final int height = rotated? 
Mimagewidth:mimageheight; 
Mdrawmatrix.postrotate (Mrotation, MIMAGEWIDTH/2, MIMAGEHEIGHT/2); 
if (rotated) {final int translatex = (width-mimagewidth)/2; 
Final int translatey = (height-mimageheight)/2; 
Mdrawmatrix.posttranslate (Translatex, Translatey); }} Mdrawmatrix.postconcat(Mbasematrix); 
Mdrawmatrix.postconcat (Msupportmatrix); 
return Mdrawmatrix; 
@Override public boolean Onscalebegin (Scalegesturedetector detector) {return true; @Override public void Onscaleend (Scalegesturedetector detector) {final float Currentscale = Getscale (Msupportmatrix) 
; 
if (Currentscale < 1.0f) {LOG.E ("Onscaleend", "currentscale==>" + Currentscale); 
RECTF boundary = Getdrawboundary (Getdrawmatrix ()); 
Post (new Animatedzoomrunnable (Currentscale, 1.0f, Boundary.centerx (), Boundary.centery ())); 
} protected RECTF getdrawboundary (Matrix matrix) {drawable drawable = getdrawable (); 
if (drawable = = null) {return mboundaryrect; 
Final int bitmapwidth = Drawable.getintrinsicwidth (); 
Final int bitmapheight = Drawable.getintrinsicheight (); 
Mboundaryrect.set (0, 0, bitmapwidth, bitmapheight); 
Matrix.maprect (Mboundaryrect); 
return mboundaryrect; public float Getscale (matrix matrix) {return (float) math.sqrt (float) Math.pow (GetValue matrix, Matrix.mscale_x), 2 + (float) Math.pow (GetValue (Matrix, matrix.mskew_y), 2)); /** * Helper Method "unpacks" a Matrix and returns the required value * * @param matrix-matrix to unpack * @ param Whichvalue-which value from matrix.m* to return * @return float-returned value */private float GetValue (matr 
IX Matrix, int whichvalue) {matrix.getvalues (mmatrixvalues); 
return Mmatrixvalues[whichvalue]; 
public void Enabledrawcropwidget (Boolean enable) {Menabledrawcropwidget = enable; } protected enum OPERATION {DRAG, SCALE} public enum Type {center_crop, center_inside} public interface Idecode 
Callback {void ondecoded (final int rotation, final Bitmap Bitmap); 
//setimagepath This method takes time and needs to display a progress bar, which listens to the public interface Onbitmaploadlistener {void Onloadprepare (); 
void Onloadfinish (); 
Private class Animatedzoomrunnable implements Runnable {private final float mfocalx, mfocaly; 
Private final long mstarttime; 
Private final float mzoomstart, mzoomend; PublIC animatedzoomrunnable (final float currentzoom, final float targetzoom, final float focalx, final float focaly) {Mfoca 
LX = Focalx; 
Mfocaly = Focaly; 
Mstarttime = System.currenttimemillis (); 
Mzoomstart = Currentzoom; 
Mzoomend = Targetzoom; 
@Override public void Run () {Float t = interpolate (); 
Float scale = Mzoomstart + T * (Mzoomend-mzoomstart); 
float Deltascale = Scale/getscale (Msupportmatrix); 
Msupportmatrix.postscale (Deltascale, Deltascale, Mfocalx, mfocaly); 
Setimagematrix (Getdrawmatrix ()); 
We Haven ' t hit our target scale yet, so post ourselves again if (T < 1f) {postonanimation (this); 
} private float interpolate () {Float T = 1f * (System.currenttimemillis ()-mstarttime)/200; 
t = math.min (1f, T); 
t = sinterpolator.getinterpolation (t); 
return t; }} <declare-styleable Name= "Life_cropimage" > <attr name= "life_crop_ratio" format= "float"/> <attr n Ame= "Life_crop_scale_type" format= "enum" > <enum name= "Life_center_"Crop "value=" 0 "/> <enum name=" Life_center_inside "value=" 1 "/> </attr> </declare-styleable> 

1, let this crop box display Picture:

Mseniorimageview.setimagepath (path);

2, Save the cropped picture:

Bitmap imageviewbitmap = null; 
try { 
imageviewbitmap = Mseniorimageview.savecrop (); 
} catch (OutOfMemoryError e) { 
Imageviewbitmap = Mseniorimageview.getoriginbitmap (); 
Pinktoast.maketext (mactivity, R.string.life_image_crop_topbar_crop_error, Toast.length_long). Show (); 

3, set the cutting ratio:

Mseniorimageview.setcropratio (3f/4f);

4, set the clipping box padding:

Mseniorimageview.setcroprectpadding (0f);

5, setImagePath This method is more time-consuming, need to show progress bar, this is monitoring:

Mseniorimageview.setbitmaploadinglistener (New Seniorcropimageview.onbitmaploadlistener () { 
@Override 
public void Onloadprepare () { 
mactivity.showprogress (); 
} 
@Override public 
void Onloadfinish () { 
mactivity.hideprogress (); 
} 
});

The above is a small set of Android for everyone to cut the picture code to share any proportion, I hope to help you

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.