android 圆形相机预览拍照_Android之圆形头像(实现相机拍摄+相册选择+图片裁剪功能)-Go语言中文社区...

功能实现:点击圆形头像之后可以实现相册上传或者开启相机,然后把得到的图片经过剪裁,把剪裁过的图片设置为头像的背景图

步骤:第一步:自定义一个类,继承ImageView,重写draw方法,实现外观为圆形

第二步:在xml文件中引用该控件

第三步:实现圆形头像的点击事件,点击后显示对话框界面,询问你是打开相册还是相机(自动省略显示对话框的代码)

第四步:根据用户选择情况,打开相册或者相机

第五步:将拍摄的图片或者相册选中的图片进行剪裁,将结果保存在指定内存区域

第六步:更新头像图片

具体实现:第一步:自定义一个类,继承ImageView,重写draw方法,实现外观为圆形

//圆形头像类

public classMyRoundPhotoextendsImageView{

private Paint p;

private Bitmap bitmap;

private Context context;

private int wAndHeight[]=new int[2];

private File file;

publicMyRoundPhoto(Context context, AttributeSet attrs,intdefStyle){

super(context, attrs, defStyle);

// TODO Auto-generated constructor stub

//获得控件长宽(px)

wAndHeight = getWidthAndHeight(context,attrs);

this.context = context;

//初始化控件

init();

}

publicMyRoundPhoto(Context context){

super(context);

// TODO Auto-generated constructor stub

//获得控件长宽(px)

wAndHeight=getWidthAndHeight(context,attrs);

this.context = context;

init();

}

publicMyRoundPhoto(Context context, AttributeSet attrs){

super(context, attrs);

//获得控件长宽(px)

wAndHeight=getWidthAndHeight(context,attrs);

// TODO Auto-generated constructor stub

this.context = context;

init();

}

@Override

protectedvoidonDraw(Canvas canvas){

// TODO Auto-generated method stub

super.onDraw(canvas);

canvas.drawBitmap(bitmap, new Matrix(), p);

}

privatevoidinit(){

//从手机存储区域获取图片文件(该位置为手机相册选中的图片经过剪裁后的图片的存储路径)

file = new File(Environment.getExternalStorageDirectory(),Info.PHOTO_NAME);

//如果图片文件存在,则显示,否则则创建并显示

if(file.exists()){

Log.v("文件存在", "是");

this.bitmap = BitmapFactory.decodeFile(file.getAbsolutePath());

}

else{

Log.v("文件不存在", "是");

//生成默认图片的文件

this.bitmap=BitmapFactory.decodeStream(context.getResources().openRawResource(R.drawable.defalut));

//person.setPicture()

FileOutputStream fos=null;

try {

fos = new FileOutputStream(file);

} catch (FileNotFoundException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos); //压缩

try {

fos.flush();

fos.close();

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

//将方形的位图转换为圆形的位图

this.bitmap = toRoundBitmap(this.bitmap);

p = new Paint();

}

privateBitmaptoRoundBitmap(Bitmap map){

//int height = map.getHeight()+100;

int height=convertDIP2PX(context,this.wAndHeight[1]); //位图的高度(px)

int width = convertDIP2PX(context,this.wAndHeight[0]);//位图的宽度(px)

//创建画布

Bitmap bit = Bitmap.createBitmap(width, height, Config.ARGB_8888);

Canvas canvas = new Canvas(bit);

//画笔

Paint paint = new Paint();

paint.setAntiAlias(false);

int r = (width>height)?height:width;

//绘制圆形

RectF rectF = new RectF(0,0,r,r);

canvas.drawRoundRect(rectF, r/2, r/2, paint);

//画头像

//canvas.drawARGB(0, 0, 0, 0);

paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));

canvas.drawBitmap(map, null,rectF, paint);

//返回圆形位图

return bit;

}

//使当前视图无效,从而使系统重新绘制视图

publicvoidmyValidate(){

bitmap = BitmapFactory.decodeFile(file.getAbsolutePath());

bitmap=toRoundBitmap(bitmap);

invalidate();

}

//将dp转换为px

privatestaticintconvertDIP2PX(Context context,intdip){

float scale = context.getResources().getDisplayMetrics().density;

return (int)(dip*scale + 0.5f*(dip>=0?1:-1));

}

//根据xml文件中的属性,返回宽高(px)

private static int[] getWidthAndHeight(Context context,AttributeSet attrs){

int height,width;

int n = attrs.getAttributeCount();

int wAndH[] = new int[2];

for(int i=0;i

String str = attrs.getAttributeName(i);

//获取宽度

if(str.equals("layout_width")){

//System.out.println(attrs.getAttributeName(0));

String sttr = attrs.getAttributeValue(i);

String temp = "";

int j=0;

while(sttr.charAt(j)>='0'&&sttr.charAt(j)<='9'){

temp+=sttr.charAt(j);

j++;

}

wAndH[0]=Integer.parseInt(temp);

temp="";

continue;

}

//获取长度

if(str.equals("layout_height")){

//System.out.println(attrs.getAttributeName(1));

String sttr = attrs.getAttributeValue(i);

String temp = "";

int j=0;

while(sttr.charAt(j)>='0'&&sttr.charAt(j)<='9'){

temp+=sttr.charAt(j);

j++;

}

//System.out.println("temp"+temp);

wAndH[1]=Integer.parseInt(temp);

temp="";

continue;

}

}

return wAndH;

}

}

第二步:在xml文件中引用该控件

第三步:实现圆形头像的点击事件,点击后显示对话框界面,询问你是打开相册还是相机(自动省略显示对话框的代码)

publicvoidonClick(View v){

// TODO Auto-generated method stub

//点击头像

if(v.getId()==R.id.myRoundPhoto){

//打开DialogActivity,询问打开照相机还是相册

Intent intent = new Intent(GuideActivity.this,DialogActivity.class);

startActivityForResult(intent, Info.PICK_PHOTO);

}

}

第四步:根据用户选择情况,打开相册或者相机

image =new File(Environment.getExternalStorageDirectory(),Info.PHOTO_NAME);

public void onClick(View v){

// TODO Auto-generated method stub

switch(v.getId()){

//打开相机

case R.id.imageButton1:{

Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");

intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(image));

startActivityForResult(intent, Info.OPEN_CAMERA);

break;

}

//打开相册

case R.id.imageButton2:{

Intent intent = new Intent(Intent.ACTION_PICK);

intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(image));

intent.setType("image/*");

startActivityForResult(intent, Info.OPEN_GALLERY);

break;

}

}

}

第五步:将拍摄的图片或者相册选中的图片进行剪裁,将结果保存在指定内存区域

protected void onActivityResult(int requestCode, int resultCode, Intent data){

// TODO Auto-generated method stub

super.onActivityResult(requestCode, resultCode, data);

switch(requestCode){

//打开相机

case Info.OPEN_CAMERA:{

if(resultCode==RESULT_OK){

//启动裁剪activity

Log.v("启动剪裁程序", "是的");

Intent intent1 = new Intent("com.android.camera.action.CROP");

intent1.setDataAndType(Uri.fromFile(image), "image/*");

intent1.putExtra("crop", "true");

intent1.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(image));//

intent1.putExtra("aspectX", 1);

intent1.putExtra("aspectY", 1);

intent1.putExtra("outputFormat", Bitmap.CompressFormat.JPEG);

intent1.putExtra("outputX", 720);

intent1.putExtra("outputY", 720);

intent1.putExtra("return-data", false);

startActivityForResult(intent1, Info.CROP_PHOTO);

}

break;

}

//打开相册

case Info.OPEN_GALLERY:{

if(resultCode==RESULT_OK){

//启动剪裁程序

Log.v("启动剪裁程序", "是的");

Intent intent1 = new Intent("com.android.camera.action.CROP");

intent1.setDataAndType(Uri.fromFile(image), "image/*");

intent1.putExtra("crop", "true");

intent1.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(image));//

intent1.putExtra("aspectX", 1);

intent1.putExtra("aspectY", 1);

intent1.putExtra("outputFormat", Bitmap.CompressFormat.JPEG);

intent1.putExtra("outputX", 720);

intent1.putExtra("outputY", 720);

intent1.putExtra("return-data", false);

startActivityForResult(intent1, Info.CROP_PHOTO);

}

break;

}

//裁剪图片

case Info.CROP_PHOTO:{

Intent intent=new Intent();

setResult(this.RESULT_OK, intent);

finish();

break;

}

}

}

第六步:更新头像图片

protected void onActivityResult(int requestCode, int resultCode, Intent data){

// TODO Auto-generated method stub

super.onActivityResult(requestCode, resultCode, data);

switch(requestCode){

//选择头像

case Info.PICK_PHOTO:{

//如果摄取图片成功

if(resultCode==RESULT_OK){

Log.v("requstCodeGuideOne", "PICK_PHOTO");

btn_choosePhoto.myValidate(); //使原有视图无效,从而使系统重新绘制视图

}

break;

}

default:{

break;

}

}

}

注意:需要添加的权限

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值