欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android仿微信QQ设置图形头像裁剪功能

程序员文章站 2024-03-04 13:04:47
最近在做毕业设计,想有一个功能和qq一样可以裁剪头像并设置圆形头像,额,这是设计狮的一种潮流。 而纵观现在主流的app,只要有用户系统这个功能,这个需求一般都是在(bu)...

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

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

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

还是先来个简单的运行图。

Android仿微信QQ设置图形头像裁剪功能

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

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

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

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

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

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

package com.example.nanchen.cropimagetest;
import android.content.context;
import android.content.res.typedarray;
import android.graphics.bitmap;
import android.graphics.bitmap.config;
import android.graphics.canvas;
import android.graphics.color;
import android.graphics.colormatrix;
import android.graphics.colormatrixcolorfilter;
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.view.motionevent;
import android.view.view;
import android.widget.imageview;
/**
* @author nanchen
* @filename cropimagetest
* @packagename com.example.nanchen.cropimagetest
* @date 2016/10/13 15:09
*/
public class roundimageview extends imageview {
/**
* 圆形imageview,可设置最多两个宽度不同且颜色不同的圆形边框。
*
* @author alan
*/
private static class imageview_level {
public final static int level0 = 0;
public final static int level1 = 1;
public final static int level2 = 2;
public final static int level3 = 3;
public final static int level4 = 4;
}
private context mcontext;
private int circlecolor = color.white;
private int circlewidth = 0;
private int mlevel = imageview_level.level1;
public void setlevel(int level) {
mlevel = level;
}
public roundimageview(context context) {
super(context);
mcontext = context;
}
public roundimageview(context context, attributeset attrs) {
super(context, attrs);
mcontext = context;
setcustomattributes(attrs);
}
public roundimageview(context context, attributeset attrs, int defstyle) {
super(context, attrs, defstyle);
mcontext = context;
setcustomattributes(attrs);
}
private void setcustomattributes(attributeset attrs) {
typedarray a = mcontext.obtainstyledattributes(attrs, r.styleable.roundedimageview);
int width = a.getdimensionpixelsize(r.styleable.roundedimageview_border_thickness, 0);
setpadding(width, width, width, width);
mlevel = a.getint(r.styleable.roundedimageview_image_mode, imageview_level.level1);
circlecolor = a.getcolor(r.styleable.roundedimageview_border_color, circlecolor);
}
@override
public void setimagebitmap(bitmap bm) {
switch (this.mlevel) {
case imageview_level.level1 :
bm = roundbitmap(bm);
case imageview_level.level2 :
if ((getpaddingleft() == getpaddingright()) && (getpaddingleft() == getpaddingbottom())
&& (getpaddingleft() == getpaddingtop())) {
this.circlewidth = getpaddingleft();
bm = roundbitmap(bm);
}
break;
case imageview_level.level3 :
bm = chamferbitmap(bm);
break;
case imageview_level.level4:
if ((getpaddingleft() == getpaddingright()) && (getpaddingleft() == getpaddingbottom())
&& (getpaddingleft() == getpaddingtop())) {
this.circlewidth = getpaddingleft();
bm = roundbitmap(bm);
}
break;
default :
break;
}
super.setimagebitmap(bm);
}
@override
protected void ondraw(canvas canvas) {
switch (this.mlevel) {
case imageview_level.level2:
if (circlewidth > 0) {
drawcircleborder(canvas, (getwidth() - this.circlewidth*2 + circlewidth) / 2, this.circlecolor, getwidth(),
getheight(), this.circlewidth);
}
break;
case imageview_level.level4:
if (circlewidth > 0){
int paddingwidth = circlewidth;
drawcircleborder(canvas, (getwidth()-paddingwidth*2 +circlewidth /2) / 2, this.circlecolor, getwidth(),
getheight(), this.circlewidth /2,color.dkgray);
int tempwidth = circlewidth /2;
drawcircleborder(canvas, (getwidth()-paddingwidth*2 +tempwidth) / 2, this.circlecolor, getwidth(),
getheight(), tempwidth,color.dkgray);
}
break;
default:
break;
}
super.ondraw(canvas);
}
/**
* bitmap切成圆形
*
* @param bitmap 传入bitmap对象
* @return
*/
private bitmap roundbitmap(bitmap bitmap) {
bitmap resultbitmap = null;
canvas canvas = null;
int width = bitmap.getwidth();
int height = bitmap.getheight();
float roundpx;
float left, top, right, bottom, dst_left, dst_top, dst_right, dst_bottom;
if (width <= height) {
roundpx = width / 2;
top = 0;
bottom = width;
left = 0;
right = width;
height = width;
dst_left = 0;
dst_top = 0;
dst_right = width;
dst_bottom = width;
} else {
roundpx = height / 2;
float clip = (width - height) / 2;
left = clip;
right = width - clip;
top = 0;
bottom = height;
width = height;
dst_left = 0;
dst_top = 0;
dst_right = height;
dst_bottom = height;
}
if (width <= 0) {
width = 1;
}
if (height <= 0) {
height = 1;
}
try {
resultbitmap = bitmap.createbitmap(width, height, config.argb_4444);
} catch (throwable e) {
e.printstacktrace();
}
try {
canvas = new canvas(resultbitmap);
} catch (throwable e) {
e.printstacktrace();
}
final int color = color.red;
final paint paint = new paint();
final rect src = new rect((int) left, (int) top, (int) right, (int) bottom);
final rect dst = new rect((int) dst_left, (int) dst_top, (int) dst_right, (int) dst_bottom);
final rectf rectf = new rectf(dst);
paint.setantialias(true);
canvas.drawargb(0, 0, 0, 0);
// paint.setcolor(color);
canvas.drawroundrect(rectf, roundpx, roundpx, paint);
paint.setxfermode(new porterduffxfermode(mode.src_in));
canvas.drawbitmap(bitmap, src, dst, paint);
return resultbitmap;
}
/**
* bitmap倒角
*
* @param bitmap 传入bitmap对象
* @return
*/
private bitmap chamferbitmap(bitmap bitmap) {
bitmap resultbitmap = null;
canvas canvas = null;
int width = bitmap.getwidth();
int height = bitmap.getheight();
float roundpx;
float left, top, right, bottom, dst_left, dst_top, dst_right, dst_bottom;
if (width <= height) {
roundpx = dip2px(this.mcontext, 4); // 8像素倒角 4是dp值
top = 0;
bottom = width;
left = 0;
right = width;
height = width;
dst_left = 0;
dst_top = 0;
dst_right = width;
dst_bottom = width;
} else {
roundpx = dip2px(this.mcontext, 4); // 8像素倒角 4是dp值
float clip = (width - height) / 2;
left = clip;
right = width - clip;
top = 0;
bottom = height;
width = height;
dst_left = 0;
dst_top = 0;
dst_right = height;
dst_bottom = height;
}
if (width <= 0) {
width = 1;
}
if (height <= 0) {
height = 1;
}
try {
resultbitmap = bitmap.createbitmap(width, height, config.argb_4444);
} catch (throwable e) {
e.printstacktrace();
}
try {
canvas = new canvas(resultbitmap);
} catch (throwable e) {
e.printstacktrace();
}
final int color = color.red;
final paint paint = new paint();
final rect src = new rect((int) left, (int) top, (int) right, (int) bottom);
final rect dst = new rect((int) dst_left, (int) dst_top, (int) dst_right, (int) dst_bottom);
final rectf rectf = new rectf(dst);
paint.setantialias(true);
canvas.drawargb(0, 0, 0, 0);
// paint.setcolor(color);
canvas.drawroundrect(rectf, roundpx, roundpx, paint);
paint.setxfermode(new porterduffxfermode(mode.src_in));
canvas.drawbitmap(bitmap, src, dst, paint);
return resultbitmap;
}
/**
* 画布画圆
*/
private void drawcircleborder(canvas canvas, int radius, int color, int width, int height, int circlewidth) {
paint paint = new paint();
/* 去锯齿 */
paint.setantialias(true);
paint.setfilterbitmap(true);
paint.setdither(true);
paint.setcolor(color);
/* 设置paint的 style 为stroke:空心 */
paint.setstyle(paint.style.stroke);
/* 设置paint的外框宽度 */
paint.setstrokewidth(circlewidth);
canvas.drawcircle(width / 2, height / 2, radius, paint);
}
private void drawcircleborder(canvas canvas, int radius, int color, int width, int height, int circlewidth,int shadowcolor){
canvas.save(); //保存画布当前状态
canvas.rotate(45,width / 2, height / 2); //右下角45度阴影投射
paint paint = new paint();
paint.setcolor(0x09ffffff & shadowcolor ); //设置alpha值
for(int i=0;i<circlewidth*2;i++) //向下角角偏移投射多少次阴影层
{
canvas.drawcircle(width/2+i, height / 2, radius+2, paint);
}
canvas.restore();
paint = new paint();
/* 去锯齿 */
paint.setantialias(true);
paint.setfilterbitmap(true);
paint.setdither(true);
paint.setcolor(color);
/* 设置paint的 style 为stroke:空心 */
paint.setstyle(paint.style.stroke);
/* 设置paint的外框宽度 */
paint.setstrokewidth(circlewidth); //二分之一实体
canvas.drawcircle(width / 2, height / 2, radius, paint);
}
public void setcirclewidth(int padding) {
setpadding(padding, padding, padding, padding);
}
public int getcirclecolor() {
return circlecolor;
}
public void setcirclecolor(int circlecolor) {
this.circlecolor = circlecolor;
}
// 执行完setimagebitmap后才能获得;
public int getcirclewidth() {
return this.circlewidth;
}
public ontouchlistener ontouchlistener = new ontouchlistener() {
@override
public boolean ontouch(view view, motionevent event) {
switch (event.getaction()) {
case motionevent.action_up:
changelight((imageview) view, 0);
// onclick
break;
case motionevent.action_down:
changelight((imageview) view, -60);
break;
case motionevent.action_move:
// changelight((imageview) view, 0);
break;
case motionevent.action_cancel:
changelight((imageview) view, 0);
break;
default:
break;
}
return false;
}
};
public void setcolorfilter(boolean value){
if(value){
setontouchlistener(ontouchlistener);
}else{
setontouchlistener(null);
}
}
private void changelight(imageview imageview, int brightness) {
colormatrix matrix = new colormatrix();
matrix.set(new float[] { 1, 0, 0, 0, brightness, 0, 1, 0, 0, brightness, 0, 0, 1, 0, brightness, 0, 0, 0, 1, 0 });
imageview.setcolorfilter(new colormatrixcolorfilter(matrix));
}
/**
* 根据手机的分辨率从 dp 的单位 转成为 px(像素)
*/
private int dip2px(context context, float dpvalue) {
final float scale = context.getapplicationcontext().getresources().getdisplaymetrics().density;
return (int) (dpvalue * scale + 0.5f);
}
}

自定义一个仿ios的弹出框

package com.example.nanchen.cropimagetest;
import android.app.activity;
import android.app.dialog;
import android.os.bundle;
import android.text.textutils;
import android.view.layoutinflater;
import android.view.view;
import android.view.view.onclicklistener;
import android.view.viewgroup;
import android.view.viewgroup.layoutparams;
import android.view.window;
import android.view.windowmanager;
import android.widget.adapterview;
import android.widget.adapterview.onitemclicklistener;
import android.widget.baseadapter;
import android.widget.button;
import android.widget.listview;
import android.widget.textview;
import java.util.list;
/**
* dialog
* 
*/
public class selectdialog extends dialog implements onclicklistener,onitemclicklistener {
private selectdialoglistener mlistener;
private activity mactivity;
private button mmbtn_cancel;
private textview mtv_title;
private list<string> mname;
private string mtitle;
private boolean musecustomcolor = false;
private int mfirstitemcolor;
private int motheritemcolor;
public interface selectdialoglistener {
public void onitemclick(adapterview<?> parent, view view, int position, long id);
}
private selectdialogcancellistener mcancellistener;
public interface selectdialogcancellistener {
public void oncancelclick(view v);
}
public selectdialog(activity activity, int theme,
selectdialoglistener listener,list<string> names) {
super(activity, theme);
mactivity = activity;
mlistener = listener;
this.mname=names;
// 设置是否点击外围解散
setcanceledontouchoutside(true);
}
/**
* @param activity 调用弹出菜单的activity
* @param theme 主题
* @param listener 菜单项单击事件
* @param cancellistener 取消事件
* @param names 菜单项名称
* 
*/
public selectdialog(activity activity, int theme,selectdialoglistener listener,selectdialogcancellistener cancellistener ,list<string> names) {
super(activity, theme);
mactivity = activity;
mlistener = listener;
mcancellistener = cancellistener;
this.mname=names;
// 设置是否点击外围不解散
setcanceledontouchoutside(false);
}
/**
* @param activity 调用弹出菜单的activity
* @param theme 主题
* @param listener 菜单项单击事件
* @param names 菜单项名称
* @param title 菜单标题文字
* 
*/
public selectdialog(activity activity, int theme,selectdialoglistener listener,list<string> names,string title) {
super(activity, theme);
mactivity = activity;
mlistener = listener;
this.mname=names;
mtitle = title;
// 设置是否点击外围可解散
setcanceledontouchoutside(true);
}
public selectdialog(activity activity, int theme,selectdialoglistener listener,selectdialogcancellistener cancellistener,list<string> names,string title) {
super(activity, theme);
mactivity = activity;
mlistener = listener;
mcancellistener = cancellistener;
this.mname=names;
mtitle = title;
// 设置是否点击外围可解散
setcanceledontouchoutside(true);
}
@override
protected void oncreate(bundle savedinstancestate) {
super.oncreate(savedinstancestate);
view view = getlayoutinflater().inflate(r.layout.view_dialog_select,
null);
setcontentview(view, new layoutparams(layoutparams.fill_parent,
layoutparams.wrap_content));
window window = getwindow();
// 设置显示动画
window.setwindowanimations(r.style.main_menu_animstyle);
windowmanager.layoutparams wl = window.getattributes();
wl.x = 0;
wl.y = mactivity.getwindowmanager().getdefaultdisplay().getheight();
// 以下这两句是为了保证按钮可以水平满屏
wl.width = layoutparams.match_parent;
wl.height = layoutparams.wrap_content;
// 设置显示位置
onwindowattributeschanged(wl);
//setcanceledontouchoutside(false);
initviews();
}
private void initviews() {
dialogadapter dialogadapter=new dialogadapter(mname);
listview dialoglist=(listview) findviewbyid(r.id.dialog_list);
dialoglist.setonitemclicklistener(this);
dialoglist.setadapter(dialogadapter);
mmbtn_cancel = (button) findviewbyid(r.id.mbtn_cancel);
mtv_title = (textview) findviewbyid(r.id.mtv_title);
//mmbtn_cancel.setonclicklistener(this);
mmbtn_cancel.setonclicklistener(new view.onclicklistener() {
@override
public void onclick(view v) {
// todo auto-generated method stub
if(mcancellistener != null){
mcancellistener.oncancelclick(v); 
}
dismiss();
}
});
if(!textutils.isempty(mtitle) && mtv_title != null){
mtv_title.setvisibility(view.visible);
mtv_title.settext(mtitle);
}else{
mtv_title.setvisibility(view.gone);
}
}
@override
public void onclick(view v) {
dismiss();
}
@override
public void onitemclick(adapterview<?> parent, view view, int position,
long id) {
mlistener.onitemclick(parent, view, position, id);
dismiss();
}
private class dialogadapter extends baseadapter {
private list<string> mstrings;
private viewholder viewholder;
private layoutinflater layoutinflater;
public dialogadapter(list<string> strings) {
this.mstrings = strings;
this.layoutinflater=mactivity.getlayoutinflater();
}
@override
public int getcount() {
// todo auto-generated method stub
return mstrings.size();
}
@override
public object getitem(int position) {
// todo auto-generated method stub
return mstrings.get(position);
}
@override
public long getitemid(int position) {
// todo auto-generated method stub
return position;
}
@override
public view getview(int position, view convertview, viewgroup parent) {
if (null == convertview) {
viewholder=new viewholder();
convertview=layoutinflater.inflate(r.layout.view_dialog_item, null);
viewholder.dialogitembutton=(textview) convertview.findviewbyid(r.id.dialog_item_bt);
convertview.settag(viewholder);
}else{
viewholder=(viewholder) convertview.gettag();
}
viewholder.dialogitembutton.settext(mstrings.get(position));
if (!musecustomcolor) {
mfirstitemcolor = mactivity.getresources().getcolor(r.color.dialog_blue);
motheritemcolor = mactivity.getresources().getcolor(r.color.dialog_blue);
}
if (1 == mstrings.size()) {
viewholder.dialogitembutton.settextcolor(mfirstitemcolor);
viewholder.dialogitembutton.setbackgroundresource(r.drawable.dialog_item_bg_only);
} else if (position == 0) {
viewholder.dialogitembutton.settextcolor(mfirstitemcolor);
viewholder.dialogitembutton.setbackgroundresource(r.drawable.dialog_item_bg_top);
} else if (position == mstrings.size() - 1) {
viewholder.dialogitembutton.settextcolor(motheritemcolor);
viewholder.dialogitembutton.setbackgroundresource(r.drawable.dialog_item_bg_buttom);
} else {
viewholder.dialogitembutton.settextcolor(motheritemcolor);
viewholder.dialogitembutton.setbackgroundresource(r.drawable.dialog_item_bg_center);
}
return convertview;
}
}
public static class viewholder {
public textview dialogitembutton;
}
/**
* 设置列表项的文本颜色
*/
public void setitemcolor(int firstitemcolor, int otheritemcolor) {
mfirstitemcolor = firstitemcolor;
motheritemcolor = otheritemcolor;
musecustomcolor = true;
}
}

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

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

再看看activity的代码和布局

package com.example.nanchen.cropimagetest;
import android.content.componentname;
import android.content.dialoginterface;
import android.content.dialoginterface.oncancellistener;
import android.content.intent;
import android.content.pm.resolveinfo;
import android.graphics.bitmap;
import android.graphics.bitmap.compressformat;
import android.net.uri;
import android.os.bundle;
import android.os.environment;
import android.provider.mediastore;
import android.provider.mediastore.images.media;
import android.support.v7.app.alertdialog;
import android.support.v7.app.alertdialog.builder;
import android.support.v7.app.appcompatactivity;
import android.view.view;
import android.widget.adapterview;
import com.example.nanchen.cropimagetest.selectdialog.selectdialoglistener;
import java.io.file;
import java.io.fileoutputstream;
import java.io.ioexception;
import java.util.arraylist;
import java.util.list;
public class mainactivity extends appcompatactivity {
private roundimageview mheadimage;
@override
protected void oncreate(bundle savedinstancestate) {
super.oncreate(savedinstancestate);
setcontentview(r.layout.activity_main);
mheadimage = (roundimageview) findviewbyid(r.id.main_roundimage);
}
private final int photo_picked_from_camera = 1; // 用来标识头像来自系统拍照
private final int photo_picked_from_file = 2; // 用来标识从相册获取头像
private final int crop_from_camera = 3;
private void geticonfromphoto(){
intent intent = new intent(intent.action_get_content, media.external_content_uri);
intent.settype("image/*");
startactivityforresult(intent, photo_picked_from_file);
}
private void selectphoto() {
list<string> list = new arraylist<>();
list.add("拍照");
list.add("相册");
showdialog(new selectdialoglistener() {
@override
public void onitemclick(adapterview<?> parent, view view, int position, long id) {
switch (position){
case 0:
geticonfromcamera();
break;
case 1:
geticonfromphoto(); // 从系统相册获取
break;
default:
break;
}
}
},list);
}
private uri imguri; // 由于android手机的图片基本都会很大,所以建议用uri,而不用bitmap
/**
* 调用系统相机拍照
*/
private void geticonfromcamera() {
intent intent = new intent(mediastore.action_image_capture);
imguri = uri.fromfile(new file(environment.getexternalstoragedirectory(),
"avatar_"+string.valueof(system.currenttimemillis())+".png"));
intent.putextra(mediastore.extra_output,imguri);
startactivityforresult(intent,photo_picked_from_camera);
}
private selectdialog showdialog(selectdialoglistener listener, list<string> list){
selectdialog dialog = new selectdialog(this,
r.style.transparentframewindowstyle,listener,list);
dialog.show();
return dialog;
}
/**
* 尝试裁剪图片
*/
private void docrop(){
final arraylist<cropoption> cropoptions = new arraylist<>();
final intent intent = new intent("com.android.camera.action.crop");
intent.settype("image/*");
list<resolveinfo> list = getpackagemanager().queryintentactivities(intent,0);
int size = list.size();
if (size == 0){
uiutil.showtoast(this,"当前不支持裁剪图片!");
return;
}
intent.setdata(imguri);
intent.putextra("outputx",300);
intent.putextra("outputy",300);
intent.putextra("aspectx",1);
intent.putextra("aspecty",1);
intent.putextra("scale",true);
intent.putextra("return-data",true);
// only one
if (size == 1){
intent intent1 = new intent(intent);
resolveinfo res = list.get(0);
intent1.setcomponent(new componentname(res.activityinfo.packagename,res.activityinfo.name));
startactivityforresult(intent1,crop_from_camera);
}else {
// 很多可支持裁剪的app
for (resolveinfo res : list) {
cropoption co = new cropoption();
co.title = getpackagemanager().getapplicationlabel(res.activityinfo.applicationinfo);
co.icon = getpackagemanager().getapplicationicon(res.activityinfo.applicationinfo);
co.appintent = new intent(intent);
co.appintent.setcomponent(new componentname(res.activityinfo.packagename,res.activityinfo.name));
cropoptions.add(co);
}
commonadapter<cropoption> adapter = new commonadapter<cropoption>(this,cropoptions,r.layout.layout_crop_selector) {
@override
public void convert(viewholder holder, cropoption item) {
holder.setimagedrawable(r.id.iv_icon,item.icon);
holder.settext(r.id.tv_name,item.title);
}
};
alertdialog.builder builder = new builder(this);
builder.settitle("choose a app");
builder.setadapter(adapter, new dialoginterface.onclicklistener() {
@override
public void onclick(dialoginterface dialog, int which) {
startactivityforresult(cropoptions.get(which).appintent,crop_from_camera);
}
});
builder.setoncancellistener(new oncancellistener() {
@override
public void oncancel(dialoginterface dialog) {
if (imguri != null){
getcontentresolver().delete(imguri,null,null);
imguri = null;
}
}
});
alertdialog dialog = builder.create();
dialog.show();
}
}
@override
protected void onactivityresult(int requestcode, int resultcode, intent data) {
super.onactivityresult(requestcode, resultcode, data);
if (resultcode != result_ok){
return;
}
switch (requestcode) {
case photo_picked_from_camera:
docrop();
break;
case photo_picked_from_file:
imguri = data.getdata();
docrop();
break;
case crop_from_camera:
if (data != null){
setcropimg(data);
}
break;
default:
break;
}
}
private void setcropimg(intent picdata){
bundle bundle = picdata.getextras();
if (bundle != null){
bitmap mbitmap = bundle.getparcelable("data");
mheadimage.setimagebitmap(mbitmap);
savebitmap(environment.getexternalstoragedirectory() + "/crop_"
+system.currenttimemillis() + ".png",mbitmap);
}
}
private void savebitmap(string filename,bitmap bitmap){
file file = new file(filename);
fileoutputstream fout = null;
try {
file.createnewfile();
fout = new fileoutputstream(file);
bitmap.compress(compressformat.png,100,fout);
fout.flush();
} catch (ioexception e) {
e.printstacktrace();
} finally {
try {
if (fout!=null){
fout.close();
}
uiutil.showtoast(mainactivity.this,"保存成功!");
} catch (ioexception e) {
e.printstacktrace();
}
}
}
public void btnclick(view view) {
selectphoto();
}
}

布局:

<?xml version="1.0" encoding="utf-8"?>
<relativelayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.nanchen.cropimagetest.mainactivity">
<com.example.nanchen.cropimagetest.roundimageview
android:id="@+id/main_roundimage"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_alignparenttop="true"
android:layout_centerinparent="true"
android:src="@drawable/default_avatar"/>
<button
android:id="@+id/main_btn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/main_roundimage"
android:onclick="btnclick"
android:text="设置头像"/>
</relativelayout>

以上所述是小编给大家介绍的android仿微信qq设置图形头像裁剪功能,希望对大家有所帮助