Android Custom Controls Imitation QQ Edit and select round Head _android

Source: Internet
Author: User
Tags gety

Android Everyone has a lot of users need to upload the avatar needs, some of the choice of square, some rounded rectangle, some round.
First we have to do a custom control of the image processing, the incoming picture, through the user selection area, processing into a certain shape.

Some apps are by drawing a rectangular area on the picture to indicate the selected content, while others are zooming in by double pointing, dragging the picture to select the picture. Round Head, or change the picture better

The circular area can be resized.

The image portion of this custom view is divided into three, background images, translucent masks, and bright areas ... Or just stick to the code.

Package com.example.jjj.widget;
Import Android.content.Context;
Import Android.graphics.Bitmap;
Import Android.graphics.Canvas;
Import Android.graphics.Color;
Import Android.graphics.Paint;
Import Android.graphics.PorterDuff.Mode;
Import Android.graphics.PorterDuffXfermode;
Import Android.graphics.Rect;
Import Android.graphics.RectF;
Import Android.util.AttributeSet;
Import Android.util.Log;
Import android.view.MotionEvent;

Import Android.view.View;
 public class Roundeditimageview extends View {private Bitmap Bitmap;
 RECTF clipbounds, DST, SRC;

 Paint Clearpaint;
 Control width High Private int w, H;

 Selection radius Private float radius = 150f;

 The boundary of the circular constituency is private RECTF circlebounds;

 The maximum magnification factor private float Max_scale = 2.0f;
 Double finger distance private float distance;
 Private float x0, y0;

 Private Boolean doublepoint;
  Public Roundeditimageview (context, AttributeSet attrs, int defstyle) {Super (context, attrs, Defstyle);
 Init (); Public Roundeditimageview, AttribUteset attrs) {Super (context, attrs);
 Init ();
  Public Roundeditimageview {Super (context);
 Init ();
  private void Init () {clearpaint = new Paint (Paint.anti_alias_flag);
  Clearpaint.setcolor (Color.gray);
 Clearpaint.setxfermode (New Porterduffxfermode (mode.clear));
  } @Override protected void OnDraw (Canvas Canvas) {Super.ondraw (Canvas); if (bitmap!= null) {canvas.drawbitmap (bitmap, NULL, DST, NULL)//Save layer every time invalidate by changing DST to zoom translation to avoid clear B when cleared
  Itmap int count = Canvas.savelayer (clipbounds, NULL, Canvas.all_save_flag);
  Canvas.drawcolor (0x80000000);
 Canvas.drawcircle (W/2, H/2, radius, clearpaint);//clear translucent black, leaving a transparent circle canvas.restoretocount (count);  @Override protected void onmeasure (int widthmeasurespec, int heightmeasurespec) {super.onmeasure (Widthmeasurespec,
 HEIGHTMEASURESPEC);
  @Override protected void onsizechanged (int w, int h, int oldw, int oldh) {super.onsizechanged (W, H, OLDW, OLDH);
THIS.W = W;  This.h = h;
  Record view occupies the rectangular clipbounds = new RECTF (0, 0, W, h);
  Float L, R, T, B; if (bitmap!= null) {//To judge the aspect ratio, when the aspect ratio is too long it will be too wide to initialize the picture in Fitcenter mode if (w/(float) H > Bitmap.getwidth ()/(float) bitm
    Ap.getheight ()) {//Picture too high float w_ = h * bitmap.getwidth ()/(float) bitmap.getheight ();
    L = w/2f-w_/2f;
    r = w/2f + w_/2f;
    t = 0;
   b = h;
    else {//Picture too long, or as long as view float H_ = w * bitmap.getheight ()/(float) bitmap.getwidth ();
    L = 0;
    R = W;
    t = h/2f-h_/2f;
   b = h/2f + h_/2f; DST = new RECTF (l, T, R, b);//This rectangle is used to transform src = new RECTF (l, T, R, b);//This rectangle only holds the first state Max_scale = Math.max (max
  _scale, Bitmap.getwidth ()/Src.width ());
 } circlebounds = new RECTF (W/2-radius, H/2-radius, W/2 + radius, H/2 + radius);
  public void Setimagebitmap (Bitmap Bitmap) {this.bitmap = Bitmap;
 Invalidate (); @Override public boolean dispatchtouchevent (Motionevent e) {if E.getpointercounT () > 2) {//Do not accept events with more than two fingers return false;
  else if (e.getpointercount () = = 2) {Doublepoint = true;//flag bit, record two fingers after event processing, lift one hand also does not handle drag handledoublemove (e);
    else {//handle a single finger-drag switch (E.getaction ()) {Case MotionEvent.ACTION_DOWN:x0 = E.getx ();
    y0 = E.gety ();
   Break
    Case MotionEvent.ACTION_MOVE:if (Doublepoint) {break;
    float x = E.getx ();
    Float y = e.gety ();
    float w = dst.width ();

    Float h = dst.height ();
    Not allowed to drag the round area, can not make the circular area blank dst.left + = x-x0;
    if (Dst.left > Circlebounds.left) {dst.left = Circlebounds.left;
    else if (Dst.left < circlebounds.right-w) {dst.left = circlebounds.right-w;

    } dst.right = Dst.left + W;
    Not allowed to drag the round area, can not make the circular area blank dst.top + = y-y0;
    if (Dst.top > Circlebounds.top) {dst.top = Circlebounds.top;
    else if (Dst.top < circlebounds.bottom-h) {dst.top = circlebounds.bottom-h;

    } Dst.bottom = Dst.top + H; x0 = X
    y0 = y;
    Invalidate ();
   Break
   Case MotionEvent.ACTION_UP:doublePoint = false;//recovery flag bit break;
 } return true; //Handle dual-fingered event private void Handledoublemove (motionevent e) {switch (E.getaction () & Motionevent.action_mask) {C
   ASE MotionEvent.ACTION_POINTER_DOWN:distance = sqrt (e);
   LOG.D ("px", "down:distance=" + distance);
  Break
   Case MotionEvent.ACTION_MOVE:scale (e);
  Break
  Case MotionEvent.ACTION_UP:break;
  Default:break;
  } private void Scale (Motionevent e) {Float dis = sqrt (e);
  The fulcrum of the double pointing Center as the picture scaling is float PX = e.getx (0)/2f + E.GETX (1)/2f;
  float PY = e.gety (0)/2f + e.gety (1)/2f;
  float scale = dis/distance;
  LOG.D ("px", "move:distance=" + Dis + ", scale to" + scale);
  float w = dst.width ();

  Float h = dst.height (); if (w * Scale < RADIUS * 2 | | H * Scale < RADIUS * 2 | | w * scale > Src.width () * Max_scale) {//cannot be reduced to smaller than the constituency, or
  Reach the maximum multiple return; ///Enlarge the DST area scale times dst.left = (dst.left-px) * scale + PX;
  Dst.right = (dst.right-px) * scale + PX;
  Dst.top = (dst.top-py) * scale + PY;

  Dst.bottom = (dst.bottom-py) * scale + PY;
   Scaling also does not allow the circular area to be blank if (Dst.left > Circlebounds.left) {dst.left = Circlebounds.left;
  Dst.right = dst.left + w * scale;
   else if (Dst.right < circlebounds.right) {dst.right = Circlebounds.right;
  Dst.left = dst.right-w * scale;
   } if (Dst.top > Circlebounds.top) {dst.top = Circlebounds.top;
  Dst.bottom = dst.top + H * scale;
   else if (Dst.bottom < circlebounds.bottom) {dst.bottom = Circlebounds.bottom;
  Dst.top = dst.bottom-h * scale;

  } invalidate ();
 distance = dis; Private float sqrt (motionevent e) {return (float) math.sqrt (e.getx (0)-e.getx (1)) * (E.GETX (0)-e.getx (1)) + (E.
 GetY (0)-e.gety (1)) * (e.gety (0)-e.gety (1))); Bitmap public Bitmap extractbitmap (int width) {Bitmap Outbitmap = Bitmap.createbitmap (width, width, for the specified size of the current selection) , Bitmap.
  config.argb_8888);
  Canvas Canvas = new Canvas (OUTBITMAP);
  Paint p = new Paint (Paint.anti_alias_flag);
  P.setcolor (Color.gray);
  Canvas.drawcircle (WIDTH/2, WIDTH/2, WIDTH/2, p);
  Float scale = Dst.width ()/bitmap.getwidth ();
  int w = (int) (Circlebounds.width ()/scale);
  int L = (int) ((circlebounds.left-dst.left)/scale);
  int r = l + W;
  int t = (int) ((circlebounds.top-dst.top)/scale);
  int b = t + W;
  Rect resrect = new Rect (l, T, R, b);
  Paint Paint = new Paint ();
  Paint.setxfermode (New Porterduffxfermode (mode.src_in));
  Canvas.drawbitmap (Bitmap, Resrect, Canvas.getclipbounds (), paint);
 return outbitmap;

 }
}

Usage in activity

 @Override
 protected void onCreate (Bundle savedinstancestate) {
  super.oncreate (savedinstancestate);
  Setcontentview (R.layout.activity_select_header);
  Roundeditimageview ImageView = (roundeditimageview) Findviewbyid (r.id.roundeditimageview1);
  Bitmap = Bitmapfactory.decodefile (ImagePath);
  Imageview.setimagebitmap (bitmap);
 }

 @Override public
 void OnClick (View v) {
   //Generate a picture of the 300*300 's current bright circle
   Bitmap result = Imageview.extractbitmap (a);
   Compressed into png
   fileoutputstream out = new FileOutputStream (new File (FilePath));
   Result.compress (Bitmap.CompressFormat.PNG, out);
   Upload and display
   ...
 }

The demand is imitate QQ, I am not very can explain, do play play.

The above is the entire content of this article, I hope to help you learn, but also hope that we support the cloud habitat community.

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.