实现显示圆形头像及选择相册相机修改头像

首先自定义一个View:CustomImageView 代码如下:

package com.example.roundimageview.view;


import com.example.roundimageview.R;


import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.RectF;
import android.graphics.Bitmap.Config;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.View;
import android.view.View.MeasureSpec;


public class CustomImageView extends View {


/**
* TYPE_CIRCLE / TYPE_ROUND
*/
private int type;
private static final int TYPE_CIRCLE = 0;
private static final int TYPE_ROUND = 1;


/**
* 图片
*/
private Bitmap mSrc;


/**
* 圆角的大小
*/
private int mRadius;


/**
* 控件的宽度
*/
private int mWidth;
/**
* 控件的高度
*/
private int mHeight;


public CustomImageView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}


public CustomImageView(Context context) {
this(context, null);
}


/**
* 初始化一些自定义的参数

* @param context
* @param attrs
* @param defStyle
*/
public CustomImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);


TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.CustomImageView, defStyle, 0);


int n = a.getIndexCount();
for (int i = 0; i < n; i++) {
int attr = a.getIndex(i);
switch (attr) {
case R.styleable.CustomImageView_src:
mSrc = BitmapFactory.decodeResource(getResources(), a.getResourceId(attr, 0));
break;
case R.styleable.CustomImageView_type:
type = a.getInt(attr, 0);// 默认为Circle
break;
case R.styleable.CustomImageView_borderRadius:
mRadius = a.getDimensionPixelSize(attr, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
10f, getResources().getDisplayMetrics()));// 默认为10DP
break;
}
}
a.recycle();
}


/**
* 计算控件的高度和宽度
*/
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// super.onMeasure(widthMeasureSpec, heightMeasureSpec);
/**
* 设置宽度
*/
int specMode = MeasureSpec.getMode(widthMeasureSpec);
int specSize = MeasureSpec.getSize(widthMeasureSpec);


if (specMode == MeasureSpec.EXACTLY)// match_parent , accurate
{
mWidth = specSize;
} else {
// 由图片决定的宽
int desireByImg = getPaddingLeft() + getPaddingRight() + mSrc.getWidth();
if (specMode == MeasureSpec.AT_MOST)// wrap_content
{
mWidth = Math.min(desireByImg, specSize);
} else


mWidth = desireByImg;
}


/***
* 设置高度
*/


specMode = MeasureSpec.getMode(heightMeasureSpec);
specSize = MeasureSpec.getSize(heightMeasureSpec);
if (specMode == MeasureSpec.EXACTLY)// match_parent , accurate
{
mHeight = specSize;
} else {
int desire = getPaddingTop() + getPaddingBottom() + mSrc.getHeight();


if (specMode == MeasureSpec.AT_MOST)// wrap_content
{
mHeight = Math.min(desire, specSize);
} else
mHeight = desire;
}


setMeasuredDimension(mWidth, mHeight);


}


/**
* 绘制
*/
@Override
protected void onDraw(Canvas canvas) {
switch (type) {
// 如果是TYPE_CIRCLE绘制圆形
case TYPE_CIRCLE:
int min = Math.min(mWidth, mHeight);
/**
* 长度如果不一致,按小的值进行压缩
*/
mSrc = Bitmap.createScaledBitmap(mSrc, min, min, false);
canvas.drawBitmap(createCircleImage(mSrc, min), 0, 0, null);
break;
case TYPE_ROUND:
canvas.drawBitmap(createRoundConerImage(mSrc), 0, 0, null);
break;


}


}


/**
* 根据原图和变长绘制圆形图片

* @param source
* @param min
* @return
*/
private Bitmap createCircleImage(Bitmap source, int min) {
final Paint paint = new Paint();
paint.setAntiAlias(true);
Bitmap target = Bitmap.createBitmap(min, min, Config.ARGB_8888);
/**
* 产生一个同样大小的画布
*/
Canvas canvas = new Canvas(target);
/**
* 首先绘制圆形
*/
canvas.drawCircle(min / 2, min / 2, min / 2, paint);
/**
* 使用SRC_IN,参考上面的说明
*/
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
/**
* 绘制图片
*/
canvas.drawBitmap(source, 0, 0, paint);
return target;
}


/**
* 根据原图添加圆角

* @param source
* @return
*/
private Bitmap createRoundConerImage(Bitmap source) {
final Paint paint = new Paint();
paint.setAntiAlias(true);
Bitmap target = Bitmap.createBitmap(mWidth, mHeight, Config.ARGB_8888);
Canvas canvas = new Canvas(target);
RectF rect = new RectF(0, 0, source.getWidth(), source.getHeight());
canvas.drawRoundRect(rect, mRadius, mRadius, paint);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
canvas.drawBitmap(source, 0, 0, paint);
return target;
}


/**
* 更换图片
* @param bitmap
*/
public void setBitmap(Bitmap bitmap){
mSrc= bitmap ; 
postInvalidate();
}
}


布局代码:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:head="http://schemas.android.com/apk/res/com.example.roundimageview"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.example.roundimageview.MainActivity" >


    <Button
        android:id="@+id/phone"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="相册" />


    <Button
        android:id="@+id/take_phone"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="拍照" />


    <com.example.roundimageview.view.CustomImageView
        android:id="@+id/my_head_image"
        android:layout_width="90dp"
        android:layout_height="90dp"
        head:borderRadius="10dp"
        head:src="@drawable/ic_launcher"
        head:type="circle" />


</LinearLayout>


activity代码:

package com.example.roundimageview;


import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;


import com.example.roundimageview.view.CustomImageView;


import android.app.Activity;
import android.content.ActivityNotFoundException;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;


public class MainActivity extends Activity implements OnClickListener {
private final int START_ALBUM_REQUESTCODE = 1;
private final int CAMERA_WITH_DATA = 2;
private final int CROP_RESULT_CODE = 3;
private Bitmap head;// 头像Bitmap
private static String path = "/sdcard/demo/myHead/";// sd路径


private Button phone, take_phone;
private CustomImageView my_head_image;


@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}


@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
phone = (Button) findViewById(R.id.phone);
take_phone = (Button) findViewById(R.id.take_phone);
my_head_image = (CustomImageView) findViewById(R.id.my_head_image);


phone.setOnClickListener(this);
take_phone.setOnClickListener(this);


Bitmap bt = BitmapFactory.decodeFile(path + "head.jpg");// 从Sd中找头像,转换成Bitmap
if (bt != null) {
@SuppressWarnings("deprecation")
Drawable drawable = new BitmapDrawable(bt);// 转换成drawable
my_head_image.setBitmap(bt);
} else {
/**
* 如果SD里面没有则需要从服务器取头像,取回来的头像再保存在SD中
*
*/
}


return true;
}


@Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch (v.getId()) {
case R.id.phone:// 相册
startAlbum();
break;
case R.id.take_phone:// 相机
startCapture();
break;


default:
break;
}


}


@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case CROP_RESULT_CODE:
if (data != null) {
Bundle extras = data.getExtras();
head = extras.getParcelable("data");
if (head != null) {
/**
* 上传服务器代码
*/
setPicToView(head);// 保存在SD卡中
// 用ImageView显示出来
my_head_image.setBitmap(head);
}
}
break;
case START_ALBUM_REQUESTCODE:
if (resultCode == RESULT_OK) {
cropPhoto(data.getData());// 裁剪图片
}
break;
case CAMERA_WITH_DATA:
// 照相机程序返回的,再次调用图片剪辑程序去修剪图片
if (resultCode == RESULT_OK) {
File temp = new File(Environment.getExternalStorageDirectory() + "/head.jpg");
cropPhoto(Uri.fromFile(temp));// 裁剪图片
}
break;
}
super.onActivityResult(requestCode, resultCode, data);
}


/**
* 相册
*/
private void startAlbum() {
try {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT, null);
intent.setType("image/*");
startActivityForResult(intent, START_ALBUM_REQUESTCODE);
} catch (ActivityNotFoundException e) {
e.printStackTrace();
try {
Intent intent = new Intent(Intent.ACTION_PICK, null);
intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*");
startActivityForResult(intent, START_ALBUM_REQUESTCODE);
} catch (Exception e2) {
// TODO: handle exception
e.printStackTrace();
}
}
}


/**
* 拍照
*/
private void startCapture() {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT,
Uri.fromFile(new File(Environment.getExternalStorageDirectory(), "head.jpg")));
startActivityForResult(intent, CAMERA_WITH_DATA);

}


/**
* 调用系统的裁剪

* @param uri
*/
public void cropPhoto(Uri uri) {
Intent intent = new Intent("com.android.camera.action.CROP");
intent.setDataAndType(uri, "image/*");
intent.putExtra("crop", "true");
// aspectX aspectY 是宽高的比例
intent.putExtra("aspectX", 1);
intent.putExtra("aspectY", 1);
// outputX outputY 是裁剪图片宽高
intent.putExtra("outputX", 150);
intent.putExtra("outputY", 150);
intent.putExtra("return-data", true);
startActivityForResult(intent, 3);
}


private void setPicToView(Bitmap mBitmap) {
String sdStatus = Environment.getExternalStorageState();
if (!sdStatus.equals(Environment.MEDIA_MOUNTED)) { // 检测sd是否可用
return;
}
FileOutputStream b = null;
File file = new File(path);
file.mkdirs();// 创建文件夹
String fileName = path + "head.jpg";// 图片名字
try {
b = new FileOutputStream(fileName);
mBitmap.compress(Bitmap.CompressFormat.JPEG, 100, b);// 把数据写入文件
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
try {
// 关闭流
b.flush();
b.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}


}


demo下载 :http://download.csdn.net/detail/wutong_7/9591887

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值