• 【绝对干货】仿微信QQ设置图形头像裁剪,让你的App从此炫起来~


    最近在做毕业设计,想有一个功能和QQ一样可以裁剪头像并设置圆形头像,额,这是设计狮的一种潮流。

    而纵观现在主流的APP,只要有用户系统这个功能,这个需求一般都是在(bu)劫(de)难(bu)逃(xue)!

    图片裁剪实现方式有两种,一种是利用系统自带的裁剪工具,一种是使用开源工具Cropper。本节就为大家带来如何使用系统自带的裁剪工具进行图片裁剪~

    还是先来个简单的运行图。(Ps,本人还没结婚,照片是我表哥~)

    额,简单说下,我待会会把代码写成小demo分享给大家,在文章末尾会附上github链接,需要的可以自行下载~

    下面来简单分析一下实现思路,我们首先照片肯定可以通过拍照和从相册选取,这个都可以向系统发送特定的Intent,响应对应的系统程序,然后在onActivityResult里面,获取我们的数据即可。而在onActivityResult里面,我们可以获取到两种形式的数据,Bitmap and uri。一般情况下我们是不会选择Bitmap的,因为大家都知道我们的手机里面的照片都太大了~强行使用bitmap,我只能说你,屌屌屌,sorry,我说的不是666,是傻屌的意思!

    哈哈哈,让我爆粗口,我原本是拒绝的~只是希望警醒在看文章的你,那么就用uri吧~

    那么然后呢?当然是对它做裁剪,完成后把这个裁剪后的bitmap对象设置给ImageView,保存起来,上传到服务器即可。

    大致了解了流程,那么我们直接看代码吧~

    先看看我们的圆形Image吧,我这个有点乱,因为考虑了很多我毕设的逻辑,所以做了一些修正,这个圆形Image相信网上会很多。

      1 package com.example.nanchen.cropimagetest;
      2 
      3 import android.content.Context;
      4 import android.content.res.TypedArray;
      5 import android.graphics.Bitmap;
      6 import android.graphics.Bitmap.Config;
      7 import android.graphics.Canvas;
      8 import android.graphics.Color;
      9 import android.graphics.ColorMatrix;
     10 import android.graphics.ColorMatrixColorFilter;
     11 import android.graphics.Paint;
     12 import android.graphics.PorterDuff.Mode;
     13 import android.graphics.PorterDuffXfermode;
     14 import android.graphics.Rect;
     15 import android.graphics.RectF;
     16 import android.util.AttributeSet;
     17 import android.view.MotionEvent;
     18 import android.view.View;
     19 import android.widget.ImageView;
     20 
     21 /**
     22  * @author nanchen
     23  * @fileName CropImageTest
     24  * @packageName com.example.nanchen.cropimagetest
     25  * @date 2016/10/13  15:09
     26  */
     27 
     28 public class RoundImageView extends ImageView {
     29 
     30     /**
     31      * 圆形ImageView,可设置最多两个宽度不同且颜色不同的圆形边框。
     32      *
     33      * @author Alan
     34      */
     35 
     36     private static class imageview_level {
     37         public final static int level0 = 0;
     38         public final static int level1 = 1;
     39         public final static int level2 = 2;
     40         public final static int level3 = 3;
     41         public final static int level4 = 4;
     42     }
     43 
     44 
     45     private Context mContext;
     46     private int circleColor = Color.WHITE;
     47     private int circleWidth = 0;
     48     private int mLevel = imageview_level.level1;
     49 
     50     public void setLevel(int level) {
     51         mLevel = level;
     52     }
     53     public RoundImageView(Context context) {
     54         super(context);
     55         mContext = context;
     56     }
     57 
     58     public RoundImageView(Context context, AttributeSet attrs) {
     59         super(context, attrs);
     60         mContext = context;
     61         setCustomAttributes(attrs);
     62     }
     63 
     64     public RoundImageView(Context context, AttributeSet attrs, int defStyle) {
     65         super(context, attrs, defStyle);
     66         mContext = context;
     67         setCustomAttributes(attrs);
     68     }
     69 
     70     private void setCustomAttributes(AttributeSet attrs) {
     71         TypedArray a = mContext.obtainStyledAttributes(attrs, R.styleable.roundedimageview);
     72         int width = a.getDimensionPixelSize(R.styleable.roundedimageview_border_thickness, 0);
     73         setPadding(width, width, width, width);
     74         mLevel = a.getInt(R.styleable.roundedimageview_image_mode, imageview_level.level1);
     75         circleColor = a.getColor(R.styleable.roundedimageview_border_color, circleColor);
     76     }
     77 
     78 
     79     @Override
     80     public void setImageBitmap(Bitmap bm) {
     81         switch (this.mLevel) {
     82             case imageview_level.level1 :
     83                 bm = RoundBitmap(bm);
     84             case imageview_level.level2 :
     85                 if ((getPaddingLeft() == getPaddingRight()) && (getPaddingLeft() == getPaddingBottom())
     86                         && (getPaddingLeft() == getPaddingTop())) {
     87                     this.circleWidth = getPaddingLeft();
     88                     bm = RoundBitmap(bm);
     89                 }
     90                 break;
     91             case imageview_level.level3 :
     92                 bm = ChamferBitmap(bm);
     93                 break;
     94             case imageview_level.level4:
     95                 if ((getPaddingLeft() == getPaddingRight()) && (getPaddingLeft() == getPaddingBottom())
     96                         && (getPaddingLeft() == getPaddingTop())) {
     97                     this.circleWidth = getPaddingLeft();
     98                     bm = RoundBitmap(bm);
     99                 }
    100                 break;
    101             default :
    102                 break;
    103         }
    104         super.setImageBitmap(bm);
    105     }
    106 
    107     @Override
    108     protected void onDraw(Canvas canvas) {
    109         switch (this.mLevel) {
    110             case imageview_level.level2:
    111                 if (circleWidth > 0) {
    112                     drawCircleBorder(canvas, (getWidth() - this.circleWidth*2 + circleWidth) / 2, this.circleColor, getWidth(),
    113                             getHeight(), this.circleWidth);
    114                 }
    115                 break;
    116             case imageview_level.level4:
    117                 if (circleWidth > 0){
    118                     int paddingwidth = circleWidth;
    119 
    120                     drawCircleBorder(canvas, (getWidth()-paddingwidth*2 +circleWidth /2) / 2, this.circleColor, getWidth(),
    121                             getHeight(), this.circleWidth /2,Color.DKGRAY);
    122 
    123                     int tempwidth = circleWidth /2;
    124                     drawCircleBorder(canvas, (getWidth()-paddingwidth*2 +tempwidth) / 2, this.circleColor, getWidth(),
    125                             getHeight(), tempwidth,Color.DKGRAY);
    126 
    127                 }
    128                 break;
    129             default:
    130                 break;
    131         }
    132         super.onDraw(canvas);
    133     }
    134 
    135     /**
    136      * bitmap切成圆形
    137      *
    138      * @param bitmap 传入Bitmap对象
    139      * @return
    140      */
    141     private Bitmap RoundBitmap(Bitmap bitmap) {
    142         Bitmap resultBitmap = null;
    143         Canvas canvas = null;
    144         int width = bitmap.getWidth();
    145         int height = bitmap.getHeight();
    146         float roundPx;
    147         float left, top, right, bottom, dst_left, dst_top, dst_right, dst_bottom;
    148         if (width <= height) {
    149             roundPx = width / 2;
    150             top = 0;
    151             bottom = width;
    152             left = 0;
    153             right = width;
    154             height = width;
    155             dst_left = 0;
    156             dst_top = 0;
    157             dst_right = width;
    158             dst_bottom = width;
    159         } else {
    160             roundPx = height / 2;
    161             float clip = (width - height) / 2;
    162             left = clip;
    163             right = width - clip;
    164             top = 0;
    165             bottom = height;
    166             width = height;
    167             dst_left = 0;
    168             dst_top = 0;
    169             dst_right = height;
    170             dst_bottom = height;
    171         }
    172         if (width <= 0) {
    173             width = 1;
    174         }
    175         if (height <= 0) {
    176             height = 1;
    177         }
    178 
    179         try {
    180             resultBitmap = Bitmap.createBitmap(width, height, Config.ARGB_4444);
    181         } catch (Throwable e) {
    182             e.printStackTrace();
    183         }
    184 
    185         try {
    186             canvas = new Canvas(resultBitmap);
    187         } catch (Throwable e) {
    188             e.printStackTrace();
    189         }
    190 
    191         final int color = Color.RED;
    192         final Paint paint = new Paint();
    193         final Rect src = new Rect((int) left, (int) top, (int) right, (int) bottom);
    194         final Rect dst = new Rect((int) dst_left, (int) dst_top, (int) dst_right, (int) dst_bottom);
    195         final RectF rectF = new RectF(dst);
    196         paint.setAntiAlias(true);
    197         canvas.drawARGB(0, 0, 0, 0);
    198         // paint.setColor(color);
    199         canvas.drawRoundRect(rectF, roundPx, roundPx, paint);
    200         paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
    201         canvas.drawBitmap(bitmap, src, dst, paint);
    202         return resultBitmap;
    203     }
    204 
    205     /**
    206      * bitmap倒角
    207      *
    208      * @param bitmap 传入Bitmap对象
    209      * @return
    210      */
    211     private Bitmap ChamferBitmap(Bitmap bitmap) {
    212         Bitmap resultBitmap = null;
    213         Canvas canvas = null;
    214         int width = bitmap.getWidth();
    215         int height = bitmap.getHeight();
    216         float roundPx;
    217         float left, top, right, bottom, dst_left, dst_top, dst_right, dst_bottom;
    218         if (width <= height) {
    219             roundPx = dip2px(this.mContext, 4); // 8像素倒角 4是dp值
    220             top = 0;
    221             bottom = width;
    222             left = 0;
    223             right = width;
    224             height = width;
    225             dst_left = 0;
    226             dst_top = 0;
    227             dst_right = width;
    228             dst_bottom = width;
    229         } else {
    230             roundPx = dip2px(this.mContext, 4); // 8像素倒角 4是dp值
    231             float clip = (width - height) / 2;
    232             left = clip;
    233             right = width - clip;
    234             top = 0;
    235             bottom = height;
    236             width = height;
    237             dst_left = 0;
    238             dst_top = 0;
    239             dst_right = height;
    240             dst_bottom = height;
    241         }
    242         if (width <= 0) {
    243             width = 1;
    244         }
    245         if (height <= 0) {
    246             height = 1;
    247         }
    248 
    249         try {
    250             resultBitmap = Bitmap.createBitmap(width, height, Config.ARGB_4444);
    251         } catch (Throwable e) {
    252             e.printStackTrace();
    253         }
    254 
    255         try {
    256             canvas = new Canvas(resultBitmap);
    257         } catch (Throwable e) {
    258             e.printStackTrace();
    259         }
    260 
    261         final int color = Color.RED;
    262         final Paint paint = new Paint();
    263         final Rect src = new Rect((int) left, (int) top, (int) right, (int) bottom);
    264         final Rect dst = new Rect((int) dst_left, (int) dst_top, (int) dst_right, (int) dst_bottom);
    265         final RectF rectF = new RectF(dst);
    266         paint.setAntiAlias(true);
    267         canvas.drawARGB(0, 0, 0, 0);
    268         // paint.setColor(color);
    269         canvas.drawRoundRect(rectF, roundPx, roundPx, paint);
    270         paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
    271         canvas.drawBitmap(bitmap, src, dst, paint);
    272         return resultBitmap;
    273     }
    274 
    275     /**
    276      * 画布画圆
    277      */
    278     private void drawCircleBorder(Canvas canvas, int radius, int color, int width, int height, int circleWidth) {
    279         Paint paint = new Paint();
    280         /* 去锯齿 */
    281         paint.setAntiAlias(true);
    282         paint.setFilterBitmap(true);
    283         paint.setDither(true);
    284         paint.setColor(color);
    285         /* 设置paint的 style 为STROKE:空心 */
    286         paint.setStyle(Paint.Style.STROKE);
    287         /* 设置paint的外框宽度 */
    288         paint.setStrokeWidth(circleWidth);
    289         canvas.drawCircle(width / 2, height / 2, radius, paint);
    290     }
    291 
    292     private void drawCircleBorder(Canvas canvas, int radius, int color, int width, int height, int circleWidth,int shadowcolor){
    293 
    294         canvas.save();  //保存画布当前状态
    295         canvas.rotate(45,width / 2, height / 2);  //右下角45度阴影投射
    296         Paint paint = new Paint();
    297         paint.setColor(0x09ffffff & shadowcolor ); //设置alpha值
    298         for(int i=0;i<circleWidth*2;i++)  //向下角角偏移投射多少次阴影层
    299         {
    300             canvas.drawCircle(width/2+i, height / 2, radius+2, paint);
    301         }
    302         canvas.restore();
    303 
    304         paint = new Paint();
    305         /* 去锯齿 */
    306         paint.setAntiAlias(true);
    307         paint.setFilterBitmap(true);
    308         paint.setDither(true);
    309         paint.setColor(color);
    310         /* 设置paint的 style 为STROKE:空心 */
    311         paint.setStyle(Paint.Style.STROKE);
    312         /* 设置paint的外框宽度 */
    313         paint.setStrokeWidth(circleWidth); //二分之一实体
    314         canvas.drawCircle(width / 2, height / 2, radius, paint);
    315     }
    316 
    317     public void setCircleWidth(int padding) {
    318         setPadding(padding, padding, padding, padding);
    319     }
    320 
    321     public int getCircleColor() {
    322         return circleColor;
    323     }
    324 
    325     public void setCircleColor(int circleColor) {
    326         this.circleColor = circleColor;
    327     }
    328 
    329     // 执行完setImageBitmap后才能获得;
    330     public int getCircleWidth() {
    331         return this.circleWidth;
    332     }
    333 
    334     public OnTouchListener onTouchListener = new OnTouchListener() {
    335         @Override
    336         public boolean onTouch(View view, MotionEvent event) {
    337             switch (event.getAction()) {
    338                 case MotionEvent.ACTION_UP:
    339                     changeLight((ImageView) view, 0);
    340                     // onclick
    341                     break;
    342                 case MotionEvent.ACTION_DOWN:
    343                     changeLight((ImageView) view, -60);
    344                     break;
    345                 case MotionEvent.ACTION_MOVE:
    346 //                 changeLight((ImageView) view, 0);
    347                     break;
    348                 case MotionEvent.ACTION_CANCEL:
    349                     changeLight((ImageView) view, 0);
    350                     break;
    351                 default:
    352                     break;
    353             }
    354             return false;
    355         }
    356     };
    357 
    358     public void setColorFilter(boolean value){
    359         if(value){
    360             setOnTouchListener(onTouchListener);
    361         }else{
    362             setOnTouchListener(null);
    363         }
    364     }
    365 
    366     private void changeLight(ImageView imageview, int brightness) {
    367         ColorMatrix matrix = new ColorMatrix();
    368         matrix.set(new float[] { 1, 0, 0, 0, brightness, 0, 1, 0, 0, brightness, 0, 0, 1, 0, brightness, 0, 0, 0, 1, 0 });
    369         imageview.setColorFilter(new ColorMatrixColorFilter(matrix));
    370     }
    371 
    372     /**
    373      * 根据手机的分辨率从 dp 的单位 转成为 px(像素)
    374      */
    375     private int dip2px(Context context, float dpValue) {
    376         final float scale = context.getApplicationContext().getResources().getDisplayMetrics().density;
    377         return (int) (dpValue * scale + 0.5f);
    378     }
    379 
    380 
    381 }

    自定义一个仿IOS的弹出框

      1 package com.example.nanchen.cropimagetest;
      2 
      3 import android.app.Activity;
      4 import android.app.Dialog;
      5 import android.os.Bundle;
      6 import android.text.TextUtils;
      7 import android.view.LayoutInflater;
      8 import android.view.View;
      9 import android.view.View.OnClickListener;
     10 import android.view.ViewGroup;
     11 import android.view.ViewGroup.LayoutParams;
     12 import android.view.Window;
     13 import android.view.WindowManager;
     14 import android.widget.AdapterView;
     15 import android.widget.AdapterView.OnItemClickListener;
     16 import android.widget.BaseAdapter;
     17 import android.widget.Button;
     18 import android.widget.ListView;
     19 import android.widget.TextView;
     20 
     21 import java.util.List;
     22 
     23 
     24 /**
     25  * dialog
     26  * 
     27  */
     28 public class SelectDialog extends Dialog implements OnClickListener,OnItemClickListener {
     29     private SelectDialogListener mListener;
     30     private Activity mActivity;
     31     private Button mMBtn_Cancel;
     32     private TextView mTv_Title;
     33     private List<String> mName;
     34     private String mTitle;
     35     private boolean mUseCustomColor = false;
     36     private int mFirstItemColor;
     37     private int mOtherItemColor;
     38     
     39     public interface SelectDialogListener {
     40         public void onItemClick(AdapterView<?> parent, View view, int position, long id);
     41     }
     42 
     43     
     44     private SelectDialogCancelListener mCancelListener;
     45     
     46     public interface SelectDialogCancelListener {
     47         public void onCancelClick(View v);
     48     }
     49 
     50     public SelectDialog(Activity activity, int theme,
     51             SelectDialogListener listener,List<String> names) {
     52         super(activity, theme);
     53         mActivity = activity;
     54         mListener = listener;
     55         this.mName=names;
     56         
     57         // 设置是否点击外围解散
     58         setCanceledOnTouchOutside(true);
     59     }
     60     
     61     /**
     62      * @param activity 调用弹出菜单的activity
     63      * @param theme 主题
     64      * @param listener 菜单项单击事件
     65      * @param cancelListener 取消事件
     66      * @param names 菜单项名称
     67      * 
     68      */
     69     public SelectDialog(Activity activity, int theme,SelectDialogListener listener,SelectDialogCancelListener cancelListener ,List<String> names) {
     70         super(activity, theme);
     71         mActivity = activity;
     72         mListener = listener;
     73         mCancelListener = cancelListener;
     74         this.mName=names;
     75         
     76         // 设置是否点击外围不解散
     77         setCanceledOnTouchOutside(false);
     78     }
     79     
     80     /**
     81      * @param activity 调用弹出菜单的activity
     82      * @param theme 主题
     83      * @param listener 菜单项单击事件
     84      * @param names 菜单项名称
     85      * @param title 菜单标题文字
     86      * 
     87      */
     88     public SelectDialog(Activity activity, int theme,SelectDialogListener listener,List<String> names,String title) {
     89         super(activity, theme);
     90         mActivity = activity;
     91         mListener = listener;
     92         this.mName=names;
     93         mTitle = title;
     94         
     95         // 设置是否点击外围可解散
     96         setCanceledOnTouchOutside(true);
     97     }
     98 
     99     public SelectDialog(Activity activity, int theme,SelectDialogListener listener,SelectDialogCancelListener cancelListener,List<String> names,String title) {
    100         super(activity, theme);
    101         mActivity = activity;
    102         mListener = listener;
    103         mCancelListener = cancelListener;
    104         this.mName=names;
    105         mTitle = title;
    106         
    107         // 设置是否点击外围可解散
    108         setCanceledOnTouchOutside(true);
    109     }
    110 
    111     @Override
    112     protected void onCreate(Bundle savedInstanceState) {
    113         super.onCreate(savedInstanceState);
    114         View view = getLayoutInflater().inflate(R.layout.view_dialog_select,
    115                 null);
    116         setContentView(view, new LayoutParams(LayoutParams.FILL_PARENT,
    117                 LayoutParams.WRAP_CONTENT));
    118         Window window = getWindow();
    119         // 设置显示动画
    120         window.setWindowAnimations(R.style.main_menu_animstyle);
    121         WindowManager.LayoutParams wl = window.getAttributes();
    122         wl.x = 0;
    123         wl.y = mActivity.getWindowManager().getDefaultDisplay().getHeight();
    124         // 以下这两句是为了保证按钮可以水平满屏
    125         wl.width = LayoutParams.MATCH_PARENT;
    126         wl.height = LayoutParams.WRAP_CONTENT;
    127 
    128         // 设置显示位置
    129         onWindowAttributesChanged(wl);
    130         
    131             //setCanceledOnTouchOutside(false);
    132         initViews();
    133     }
    134 
    135     private void initViews() {
    136         DialogAdapter dialogAdapter=new DialogAdapter(mName);
    137         ListView dialogList=(ListView) findViewById(R.id.dialog_list);
    138         dialogList.setOnItemClickListener(this);
    139         dialogList.setAdapter(dialogAdapter);
    140         mMBtn_Cancel = (Button) findViewById(R.id.mBtn_Cancel);
    141         mTv_Title = (TextView) findViewById(R.id.mTv_Title);
    142         
    143             //mMBtn_Cancel.setOnClickListener(this);
    144 
    145         mMBtn_Cancel.setOnClickListener(new View.OnClickListener() {
    146             
    147             @Override
    148             public void onClick(View v) {
    149                 // TODO Auto-generated method stub
    150                 if(mCancelListener != null){
    151                     mCancelListener.onCancelClick(v);    
    152                 }
    153                 dismiss();
    154             }
    155         });
    156         
    157         if(!TextUtils.isEmpty(mTitle) && mTv_Title != null){
    158             mTv_Title.setVisibility(View.VISIBLE);
    159             mTv_Title.setText(mTitle);
    160         }else{
    161             mTv_Title.setVisibility(View.GONE);
    162         }
    163     }
    164 
    165     @Override
    166     public void onClick(View v) {
    167         dismiss();
    168 
    169     }
    170 
    171     @Override
    172     public void onItemClick(AdapterView<?> parent, View view, int position,
    173             long id) {
    174         
    175         mListener.onItemClick(parent, view, position, id);
    176         dismiss();
    177     }
    178     private class DialogAdapter extends BaseAdapter {
    179         private List<String> mStrings;
    180         private Viewholder viewholder;
    181         private LayoutInflater layoutInflater;
    182         public DialogAdapter(List<String> strings) {
    183             this.mStrings = strings;
    184             this.layoutInflater=mActivity.getLayoutInflater();
    185         }
    186 
    187         @Override
    188         public int getCount() {
    189             // TODO Auto-generated method stub
    190             return mStrings.size();
    191         }
    192 
    193         @Override
    194         public Object getItem(int position) {
    195             // TODO Auto-generated method stub
    196             return mStrings.get(position);
    197         }
    198 
    199         @Override
    200         public long getItemId(int position) {
    201             // TODO Auto-generated method stub
    202             return position;
    203         }
    204 
    205         @Override
    206         public View getView(int position, View convertView, ViewGroup parent) {
    207             if (null == convertView) {
    208                 viewholder=new Viewholder();
    209                 convertView=layoutInflater.inflate(R.layout.view_dialog_item, null);
    210                 viewholder.dialogItemButton=(TextView) convertView.findViewById(R.id.dialog_item_bt);
    211                 convertView.setTag(viewholder);
    212             }else{
    213                 viewholder=(Viewholder) convertView.getTag();
    214             }
    215             viewholder.dialogItemButton.setText(mStrings.get(position));
    216             if (!mUseCustomColor) {
    217                 mFirstItemColor = mActivity.getResources().getColor(R.color.dialog_blue);
    218                 mOtherItemColor = mActivity.getResources().getColor(R.color.dialog_blue);
    219             }
    220             if (1 == mStrings.size()) {
    221                 viewholder.dialogItemButton.setTextColor(mFirstItemColor);
    222                 viewholder.dialogItemButton.setBackgroundResource(R.drawable.dialog_item_bg_only);
    223             } else if (position == 0) {
    224                 viewholder.dialogItemButton.setTextColor(mFirstItemColor);
    225                 viewholder.dialogItemButton.setBackgroundResource(R.drawable.dialog_item_bg_top);
    226             } else if (position == mStrings.size() - 1) {
    227                 viewholder.dialogItemButton.setTextColor(mOtherItemColor);
    228                 viewholder.dialogItemButton.setBackgroundResource(R.drawable.dialog_item_bg_buttom);
    229             } else {
    230                 viewholder.dialogItemButton.setTextColor(mOtherItemColor);
    231                 viewholder.dialogItemButton.setBackgroundResource(R.drawable.dialog_item_bg_center);
    232             }
    233             return convertView;
    234         }
    235 
    236     }
    237 
    238     public static class Viewholder {
    239         public TextView dialogItemButton;
    240     }
    241 
    242     /**
    243      * 设置列表项的文本颜色
    244      */
    245     public void setItemColor(int firstItemColor, int otherItemColor) {
    246         mFirstItemColor = firstItemColor;
    247         mOtherItemColor = otherItemColor;
    248         mUseCustomColor = true;
    249     }
    250     
    251 }

    由于图片文件一定在相册中,有可能你也会在文件系统中其他地方选择,这里我采用之前写的万能适配器

    由于楼主时间的确比较紧,所以代码都是直接copy上来的,有些地方没做完全优化还望大家见谅!

    再看看Activity的代码和布局

      1 package com.example.nanchen.cropimagetest;
      2 
      3 import android.content.ComponentName;
      4 import android.content.DialogInterface;
      5 import android.content.DialogInterface.OnCancelListener;
      6 import android.content.Intent;
      7 import android.content.pm.ResolveInfo;
      8 import android.graphics.Bitmap;
      9 import android.graphics.Bitmap.CompressFormat;
     10 import android.net.Uri;
     11 import android.os.Bundle;
     12 import android.os.Environment;
     13 import android.provider.MediaStore;
     14 import android.provider.MediaStore.Images.Media;
     15 import android.support.v7.app.AlertDialog;
     16 import android.support.v7.app.AlertDialog.Builder;
     17 import android.support.v7.app.AppCompatActivity;
     18 import android.view.View;
     19 import android.widget.AdapterView;
     20 
     21 import com.example.nanchen.cropimagetest.SelectDialog.SelectDialogListener;
     22 
     23 import java.io.File;
     24 import java.io.FileOutputStream;
     25 import java.io.IOException;
     26 import java.util.ArrayList;
     27 import java.util.List;
     28 
     29 public class MainActivity extends AppCompatActivity {
     30 
     31     private RoundImageView mHeadImage;
     32 
     33     @Override
     34     protected void onCreate(Bundle savedInstanceState) {
     35         super.onCreate(savedInstanceState);
     36         setContentView(R.layout.activity_main);
     37 
     38         mHeadImage = (RoundImageView) findViewById(R.id.main_roundImage);
     39     }
     40 
     41     private final int PHOTO_PICKED_FROM_CAMERA = 1; // 用来标识头像来自系统拍照
     42     private final int PHOTO_PICKED_FROM_FILE = 2; // 用来标识从相册获取头像
     43     private final int CROP_FROM_CAMERA = 3;
     44 
     45     private void getIconFromPhoto(){
     46         Intent intent = new Intent(Intent.ACTION_GET_CONTENT, Media.EXTERNAL_CONTENT_URI);
     47         intent.setType("image/*");
     48         startActivityForResult(intent, PHOTO_PICKED_FROM_FILE);
     49     }
     50 
     51     private void selectPhoto() {
     52         List<String> list = new ArrayList<>();
     53         list.add("拍照");
     54         list.add("相册");
     55         showDialog(new SelectDialogListener() {
     56             @Override
     57             public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
     58                 switch (position){
     59                     case 0:
     60                         getIconFromCamera();
     61                         break;
     62                     case 1:
     63                         getIconFromPhoto(); // 从系统相册获取
     64                         break;
     65                     default:
     66                         break;
     67                 }
     68             }
     69         },list);
     70 
     71     }
     72 
     73     private Uri imgUri; // 由于android手机的图片基本都会很大,所以建议用Uri,而不用Bitmap
     74 
     75     /**
     76      * 调用系统相机拍照
     77      */
     78     private void getIconFromCamera() {
     79         Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
     80         imgUri = Uri.fromFile(new File(Environment.getExternalStorageDirectory(),
     81                 "avatar_"+String.valueOf(System.currentTimeMillis())+".png"));
     82         intent.putExtra(MediaStore.EXTRA_OUTPUT,imgUri);
     83         startActivityForResult(intent,PHOTO_PICKED_FROM_CAMERA);
     84     }
     85 
     86     private SelectDialog showDialog(SelectDialogListener listener, List<String> list){
     87         SelectDialog dialog = new SelectDialog(this,
     88                 R.style.transparentFrameWindowStyle,listener,list);
     89             dialog.show();
     90         return dialog;
     91     }
     92 
     93 
     94     /**
     95      * 尝试裁剪图片
     96      */
     97     private void doCrop(){
     98         final ArrayList<CropOption> cropOptions = new ArrayList<>();
     99         final Intent intent = new Intent("com.android.camera.action.CROP");
    100         intent.setType("image/*");
    101         List<ResolveInfo> list = getPackageManager().queryIntentActivities(intent,0);
    102         int size = list.size();
    103         if (size == 0){
    104             UIUtil.showToast(this,"当前不支持裁剪图片!");
    105             return;
    106         }
    107         intent.setData(imgUri);
    108         intent.putExtra("outputX",300);
    109         intent.putExtra("outputY",300);
    110         intent.putExtra("aspectX",1);
    111         intent.putExtra("aspectY",1);
    112         intent.putExtra("scale",true);
    113         intent.putExtra("return-data",true);
    114 
    115         // only one
    116         if (size == 1){
    117             Intent intent1 = new Intent(intent);
    118             ResolveInfo res = list.get(0);
    119             intent1.setComponent(new ComponentName(res.activityInfo.packageName,res.activityInfo.name));
    120             startActivityForResult(intent1,CROP_FROM_CAMERA);
    121         }else {
    122             // 很多可支持裁剪的app
    123             for (ResolveInfo res : list) {
    124                 CropOption co = new CropOption();
    125                 co.title = getPackageManager().getApplicationLabel(res.activityInfo.applicationInfo);
    126                 co.icon = getPackageManager().getApplicationIcon(res.activityInfo.applicationInfo);
    127                 co.appIntent = new Intent(intent);
    128                 co.appIntent.setComponent(new ComponentName(res.activityInfo.packageName,res.activityInfo.name));
    129                 cropOptions.add(co);
    130             }
    131 
    132             CommonAdapter<CropOption> adapter = new CommonAdapter<CropOption>(this,cropOptions,R.layout.layout_crop_selector) {
    133                 @Override
    134                 public void convert(ViewHolder holder, CropOption item) {
    135                     holder.setImageDrawable(R.id.iv_icon,item.icon);
    136                     holder.setText(R.id.tv_name,item.title);
    137                 }
    138             };
    139 
    140             AlertDialog.Builder builder = new Builder(this);
    141             builder.setTitle("choose a app");
    142             builder.setAdapter(adapter, new DialogInterface.OnClickListener() {
    143                 @Override
    144                 public void onClick(DialogInterface dialog, int which) {
    145                     startActivityForResult(cropOptions.get(which).appIntent,CROP_FROM_CAMERA);
    146                 }
    147             });
    148             builder.setOnCancelListener(new OnCancelListener() {
    149                 @Override
    150                 public void onCancel(DialogInterface dialog) {
    151                     if (imgUri != null){
    152                         getContentResolver().delete(imgUri,null,null);
    153                         imgUri = null;
    154                     }
    155                 }
    156             });
    157             AlertDialog dialog = builder.create();
    158             dialog.show();
    159 
    160         }
    161     }
    162 
    163 
    164     @Override
    165     protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    166         super.onActivityResult(requestCode, resultCode, data);
    167         if (resultCode != RESULT_OK){
    168             return;
    169         }
    170         switch (requestCode) {
    171             case PHOTO_PICKED_FROM_CAMERA:
    172                 doCrop();
    173                 break;
    174             case PHOTO_PICKED_FROM_FILE:
    175                 imgUri = data.getData();
    176                 doCrop();
    177                 break;
    178             case CROP_FROM_CAMERA:
    179                 if (data != null){
    180                     setCropImg(data);
    181                 }
    182                 break;
    183             default:
    184                 break;
    185         }
    186     }
    187 
    188     private void setCropImg(Intent picData){
    189         Bundle bundle = picData.getExtras();
    190         if (bundle != null){
    191             Bitmap mBitmap = bundle.getParcelable("data");
    192             mHeadImage.setImageBitmap(mBitmap);
    193             saveBitmap(Environment.getExternalStorageDirectory() + "/crop_"
    194                     +System.currentTimeMillis() + ".png",mBitmap);
    195         }
    196     }
    197 
    198     private void saveBitmap(String fileName,Bitmap bitmap){
    199         File file = new File(fileName);
    200         FileOutputStream fout = null;
    201         try {
    202             file.createNewFile();
    203             fout = new FileOutputStream(file);
    204             bitmap.compress(CompressFormat.PNG,100,fout);
    205             fout.flush();
    206         } catch (IOException e) {
    207             e.printStackTrace();
    208         } finally {
    209             try {
    210                 if (fout!=null){
    211                     fout.close();
    212                 }
    213                 UIUtil.showToast(MainActivity.this,"保存成功!");
    214             } catch (IOException e) {
    215                 e.printStackTrace();
    216             }
    217         }
    218     }
    219 
    220     public void btnClick(View view) {
    221         selectPhoto();
    222     }
    223 }

    布局:

     1 <?xml version="1.0" encoding="utf-8"?>
     2 <RelativeLayout
     3     xmlns:android="http://schemas.android.com/apk/res/android"
     4     xmlns:tools="http://schemas.android.com/tools"
     5     android:id="@+id/activity_main"
     6     android:layout_width="match_parent"
     7     android:layout_height="match_parent"
     8     tools:context="com.example.nanchen.cropimagetest.MainActivity">
     9 
    10 
    11     <com.example.nanchen.cropimagetest.RoundImageView
    12         android:id="@+id/main_roundImage"
    13         android:layout_width="100dp"
    14         android:layout_height="100dp"
    15         android:layout_alignParentTop="true"
    16         android:layout_centerInParent="true"
    17         android:src="@drawable/default_avatar"/>
    18 
    19     <Button
    20         android:id="@+id/main_btn"
    21         android:layout_width="match_parent"
    22         android:layout_height="wrap_content"
    23         android:layout_below="@+id/main_roundImage"
    24         android:onClick="btnClick"
    25         android:text="设置头像"/>
    26 </RelativeLayout>

    最后,再次对大家表示歉意,代码有些地方讲解不是很到位,后面我把毕设完全做出来后也会开源给大家,供大家一起交流使用,请持续关注~

     github链接:https://github.com/nanchen2251/CropImageDemo

  • 相关阅读:
    No architectures to compile for (ONLY_ACTIVE_ARCH=YES, active arch=arm64, VALID_ARCHS=armv7 armv7s).
    播放器 倒计时 闹钟 日期 分秒 时间算法
    iOS 8 以后获取地图坐标:
    数据存储(直接写入、NSUserDefaults、NSkeyedArchiver)
    图片处理 模糊效果
    手把手教你Windows下Go语言的环境搭建
    github 上传或删除 文件 命令
    域名解析-delphi 源码
    指针与引用
    指针
  • 原文地址:https://www.cnblogs.com/liushilin/p/5956691.html
Copyright © 2020-2023  润新知