Image cropping control -- ClipImageView,

Source: Internet
Author: User

Image cropping control -- ClipImageView,

During this period of time, I needed to use the image cropping function when I was working on my own project. At that time, I thought about some requirements and thought of a simple implementation method, so I took some time to make this image cropping control -- ClipImageView

Paste the ClipImageView code here:

Package com. example. clipimage; import android. content. context; import android. graphics. bitmap; import android. graphics. bitmapFactory; import android. graphics. canvas; import android. graphics. color; import android. graphics. paint; import android. graphics. rect; import android. graphics. drawable. bitmapDrawable; import android. graphics. drawable. drawable; import android. util. attributeSet; import android. view. motionEv Ent; import android. widget. imageView;/*** specifies the image cropping control. Note: 1. when setting an image for ClipImageView (call setImageResource (), * setImageDrawable (), setImageBitmap (), pay attention to the image size, that is, note that Bitmap may cause oom problems in the program. * 2. If you have no requirements on the quality of the cropped image, we recommend that you call setImageResourceSecure (), setImageDrawableSecure (), and * setImageBitmapSecure () to set the image. ** @ Author freeman. wu **/public class ClipImageView extends ImageView {private float currX; private float currY; private float dX; private float dY; private float oldX; private float oldY; private int maxX; private int maxY; private final float density = getResources (). getDisplayMetrics (). density; // density private float mClipFrameBorderWidth = 1 * density; // The Border width of the cropping box is private int mClipFrameWidth = 350; // default The width of the cropping box is private int mClipFrameHeight = 350; // The height of the default cropping box is private int imWidth; // The width of the ClipImageView is private int imHeight; // The height of ClipImageView is private boolean showClipFrame = true; // whether to display the cropping box private String mClipFrameColor = "# FFFFFFFF "; // The border color of the cropping box is private String mShadowColor = "#99000000"; // The shadow color is private Paint mShadowPaint and private Paint mClipFramePaint; /*** specifies the shadow outside the cropping box */private Rect mRectLeftShadow; private Rect mRectRightShadow; private Rect mRectTopShadow; private Rect mRectBottomShadow;/*** cropping box */private Rect mClipFrame;/*** set Bitmap */private Bitmap source in ImageView; public ClipImageView (Context context, AttributeSet attrs) {super (context, attrs); setAdjustViewBounds (true); initPaint (); initRect (); post (new Runnable () {@ Overridepublic void run () {imWidth = getWidth (); imHeight = getHeight (); resolveC LipFrameSize (); // necessary steps to correct the size of the cropping box, And maxX = imWidth-mClipFrameWidth; maxY = imHeight-mClipFrameHeight; currX = (float) maxX/2; currY = (float) maxY/2; // set the cropping box to display in the middle of the image setShadowRegion (currX, currY); setClipFramePosition (currX, currY) ;}}) ;}private void initPaint () {mShadowPaint = new Paint (); mShadowPaint. setColor (Color. parseColor (mShadowColor); mClipFramePaint = new Paint (); mClipFrame Paint. setStyle (Paint. style. STROKE); // set it to a hollow mClipFramePaint. setStrokeWidth (mClipFrameBorderWidth); // sets the Border Width setClipFrameColor (mClipFrameColor); // sets the color} private void initRect () {/*** Shadow Region */mRectLeftShadow = new Rect (); mRectTopShadow = new Rect (); mRectRightShadow = new Rect (); mRectBottomShadow = new Rect (); // cropping box mClipFrame = new Rect ();}/*** sets the position of the cropping box ** @ param x * @ param y */private void setClip FramePosition (float x, float y) {int dx = (int) (mClipFrameBorderWidth/2); mClipFrame. set (int) x + dx, (int) y + dx, (int) x + mClipFrameWidth-dx, (int) y + mClipFrameHeight-dx );} /*** set the shadow outside the cropping box ** @ param x * X coordinate in the upper left corner of the cropping box * @ param y * Y coordinate in the upper left corner of the cropping box */private void setShadowRegion (float x, float y) {mRectLeftShadow. set (0, 0, (int) x, imHeight); mRectTopShadow. set (int) x, 0, (int) x + mClipFrame Width, (int) y); mRectRightShadow. set (int) x + mClipFrameWidth, 0, imWidth, imHeight); mRectBottomShadow. set (int) x, (int) y + mClipFrameHeight, (int) x + mClipFrameWidth, imHeight);}/*** the method compresses the image pointed to by resId, this method is used to set the image. The quality of the cropped image is relatively poor, but the OOM of Bitmap can be avoided. to crop the source image, you can directly call setImageResource () ** @ param resId */public void setImageResourceSecure (int resId) {Bitmap bm = BitmapFactory. decodeResource (getRes Ources (), resId); setImageBitmap (processBitmap (bm);}/*** has compressed the image directed by drawable. Use this method to set the image, the quality of the cropped image is relatively poor, but the OOM of Bitmap can be avoided simply. to crop the source image, call setImageDrawable () ** @ param drawable */public void setImageDrawableSecure (Drawable drawable) {if (drawable = null) throw new partition ("drawable cannot be null"); BitmapDrawable bd = (BitmapDrawable) drawable; setImageBitmap (processBitmap (bd. getBitmap ();}/*** The image pointed to by bm has been compressed. This method is used to set the image. The quality of the cropped image is relatively poor, however, it is easy to avoid the OOM of Bitmap. to crop the source image, call setImageBitmap () ** @ param bm */public void setImageBitmapSecure (Bitmap bm) {setImageBitmap (processBitmap (bm);}/*** simple processing of Bitmap, properly compress the image size ** @ param bm * @ return */private Bitmap processBitmap (Bitmap bm) {if (bm = null) throw new IllegalArgumentException ("bitmap cannot be null"); int screenWidth = getResources (). GetDisplayMetrics (). widthPixels; int screenHeight = getResources (). getDisplayMetrics (). heightPixels; int bmWidth = bm. getWidth (); int bmHeight = bm. getHeight (); if (bmWidth <screenWidth | bmHeight <screenHeight) return bm; float scale = (float) screenWidth/bmWidth; Bitmap bitmap = Bitmap. createScaledBitmap (bm, screenWidth, (int) (bmHeight * scale), true); bm. recycle (); return bitmap;}/*** obtain the settings in ClipIm Bitmap ** @ return */public Bitmap getSourceBitmap () {if (source! = Null) return source; Drawable d = getDrawable (); if (d = null) {return null;} BitmapDrawable bd = (BitmapDrawable) d; source = bd. getBitmap (); return source;}/*** get the image zoom ratio of ImageView to the source image ** @ return */public float getScale () {if (getSourceBitmap () = null) return 0f; int bmWidth = source. getWidth (); int bmHeight = source. getHeight (); float scale = Math. min (float) bmWidth/imWidth, (float) bmHeight/imHeigh T); return scale;}/*** get the cropped bitmap ** @ return */public Bitmap getClippedBitmap () {float scale = getScale (); if (scale> 0 & source! = Null) return ClipImageUtils. clipImage (source, (int) currX, (int) currY, // crop an image (int) mClipFrameWidth, (int) mClipFrameHeight, scale); return null ;} /*** set the color of the border of the cropping box. Supported values include # RRGGBB # 20.rggbb 'red', 'Blue ', 'green', 'black', and 'white ', * 'Gray ', 'cyn', 'magenta', 'yellow', 'lightgray ', 'dark', 'Gray', * 'lightgrey', 'darkgrey ', 'aqua', 'fuschia ', 'lime', 'maron', 'navy', * 'live', 'purple ', 'sil ', 'Temal' ** @ param color */public void setClipFrameColor (String color) {mClipFramePaint. setColor (Color. parseColor (color);}/*** set the width and height of the cropping box ** @ param width * @ param height */public void setClipFrameSize (int width, int height) {mClipFrameWidth = width; mClipFrameHeight = height; maxX = imWidth-mClipFrameWidth; maxY = imHeight-mClipFrameHeight;}/*** corrected the width and height of the cropping box, so that it cannot exceed the width and height of the View */private void Resolv1_framesize () {mClipFrameWidth = mClipFrameWidth> = imWidth? ImWidth: mClipFrameWidth; mClipFrameHeight = mClipFrameHeight> = imHeight? ImHeight: mClipFrameHeight;}/*** set the Border width of the cropping box ** @ param w */public void setClipFrameBorderWidth (float w) {w = w <0? 0: w; mClipFrameBorderWidth = w; mClipFramePaint. setStrokeWidth (mClipFrameBorderWidth);}/*** X coordinate in the upper left corner of the cropped content ** @ return */public float getContentX () {return currX ;} /*** Y coordinate in the upper left corner of the cropped content ** @ return */public float getContentY () {return currY ;} /*** get the width of the cropped content ** @ return */public int getContentWidth () {return mClipFrameWidth ;} /*** get the height of the cropped content ** @ return */public int getContentHeight () {return mClipFrameHei Ght;} public int getImWidth () {return imWidth;} public int getImHeight () {return imHeight ;} /*** set whether to display the cropping box ** @ param f */public void setShowClipFrame (boolean f) {showClipFrame = f ;}@ Overrideprotected void onDraw (Canvas canvas Canvas) {super. onDraw (canvas); if (showClipFrame) {drawShadowRegion (canvas); drawClipFrame (canvas );}} /*** draw the shadow outside the cropping box ** @ param canvas */private void drawShadowRegion (Canvas canvas) {c Anvas. drawRect (mRectLeftShadow, mShadowPaint); canvas. drawRect (mRectTopShadow, mShadowPaint); canvas. drawRect (mRectRightShadow, mShadowPaint); canvas. drawRect (mRectBottomShadow, mShadowPaint);}/*** draw a cropping box ** @ param canvas */private void drawClipFrame (Canvas canvas) {canvas. drawRect (mClipFrame, mClipFramePaint);} @ Overridepublic boolean onTouchEvent (MotionEvent event) {switch (event. getAction () {case MotionEvent. ACTION_DOWN: oldX = event. getX (); oldY = event. getY (); break; case MotionEvent. ACTION_MOVE: if (mClipFrame. contains (int) oldX, (int) oldY) {dX = event. getX ()-oldX; dY = event. getY ()-oldY; oldX = event. getX (); oldY = event. getY (); currX + = dX; currY + = dY; // make sure that the cropping box does not exceed the ImageView range. currX = currX> maxX? MaxX: currX; currX = currX <0? 0: currX; currY = currY> maxY? MaxY: currY; currY = currY <0? 0: currY; setShadowRegion (currX, currY); // set setClipFramePosition (currX, currY) in the shadow area; // set the invalidate ();} break ;} return true ;}}

The following is the code for cropping tool ClipImageUtils:

Package com. example. clipimage; import android. graphics. bitmap;/*** cropping tool class ** @ author freeman. wu **/public class ClipImageUtils {/*** cropping the source bitmap ** @ param source * @ param x * @ param y * @ param width * width of the cropped content *@ param height * height of the cropped content * @ param imWidth * @ param imHeight * @ return */public static Bitmap clipImage (Bitmap source, int x, int y, int width, int height, int imWidth, int imHeight) {int bmWid Th = source. getWidth (); int bmHeight = source. getHeight (); float scale = Math. min (float) bmWidth/imWidth, (float) bmHeight/imHeight); return clipImage (source, x, y, width, height, scale );} /*** crop the source bitmap ** @ param source * @ param x * @ param y * @ param width * width of the cropped content * @ param height * height of the cropped content * @ param scale * cropping ratio * @ return */public static Bitmap clipImage (Bitmap source, int x, int y, int width, I Nt height, float scale) {int bmWidth = source. getWidth (); int bmHeight = source. getHeight (); x * = scale; y * = scale; width * = scale; height * = scale;/*** correct x, y value */x = (x + width> bmWidth )? BmWidth-width: x; x = x <0? 0: x; y = (y + height> bmHeight )? BmHeight-height: y; y = y <0? 0: y; return Bitmap. createBitmap (source, x, y, width, height );}}

Since the implementation method is simple, I don't have to worry much about it. Here I will briefly explain the idea of implementing the control:

1. Controls are inherited from ImageView. To draw the image view to the cropping control, you must override the onDraw () method and then draw the image.

2. In onDraw (), there are two main objects to be drawn. The first is the cropping box, and the second is the shadow outside the cropping box.

3. Use the cropping tool class to crop the content in the cropping box in ClipImageView from the original image.


This is the basic content, and the control is very convenient to use, so I will not release the demo. If you need a demo, leave a message.

For more information, see http://blog.csdn.net/wuzhipeng1991/article/details/41120583,thank you!

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.