类似于QQ设置头像,裁剪,然后上传服务端。我将自己在实际项目中的做过的此类功能顺便总结下,写了如下的demo,以供参考。
先看效果图:
其中第一个ImageView 是按照相册中的图片和8:3的比例裁剪
第二个ImageView 是按照拍照获取图片和1:1的比例裁剪
布局比较简单,所以不上布局代码,直接上MainActivity中的代码:
代码中都有详细的注释,所以不再做特别说明了。
/**
* @author hxy
*分别从照相机或是gallery中获取图片,
*分别裁剪成不同的图片,并展示在不同的控件上,最后上传到服务器
*
*/
public class MainActivity extends Activity {
/**** 从camera中和gallery中获取的图片都用uri保存 *****/
private Button mUploadBtn;
private ImageView showImageView;
private ImageView showImageView1;
private static final int SELECT_CAMERA = 1;
private static final int SELECT_PICTURE = 0;
private static final int CROP_IMAGE2 = 3;
private static final int CROP_IMAGE1 = 2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
inintView();
dealButtonClick();
}
private void dealButtonClick() {
// 点击button的时候,跳出拍照还是从相册中获取的dialog
mUploadBtn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
showDialog();
}
});
}
private void showDialog() {
CharSequence[] items = { "相册", "相机" };
new AlertDialog.Builder(this).setTitle("选择图片来源")
.setItems(items, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (which == 0) {
Intent intent = new Intent(
Intent.ACTION_GET_CONTENT);
intent.setType("image/*");
startActivityForResult(intent, SELECT_PICTURE);
} else {
Intent intent = new Intent(
MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, SELECT_CAMERA);
}
}
}).create().show();
}
private void inintView() {
mUploadBtn = (Button) findViewById(R.id.btn_take);
showImageView = (ImageView) findViewById(R.id.iv_show1);
showImageView1 = (ImageView) findViewById(R.id.iv_show2);
}
//处理返回的结果
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case SELECT_PICTURE:
getPicture(data);
break;
case SELECT_CAMERA:
getCamera(data);
break;
case CROP_IMAGE1:
if (data == null) {
return;
}
Bundle extras = data.getExtras();
if (extras == null) {
return;
}
Bitmap bm = extras.getParcelable("data");
showImageView.setImageBitmap(bm);
//TODO 上传到服务端
//sendImageToServer(bm);
break;
case CROP_IMAGE2:
if (data == null) {
return;
}
Bundle extras2 = data.getExtras();
if (extras2 == null) {
return;
}
Bitmap bm2 = extras2.getParcelable("data");
showImageView1.setImageBitmap(bm2);
//TODO 上传到服务端
//sendImageToServer(bm2);
break;
default:
break;
}
}
private void sendImageToServer(Bitmap bm) {
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bm.compress(Bitmap.CompressFormat.JPEG, 85, stream);
byte[] bytes = stream.toByteArray();
String imgStr = new String(Base64.encodeToString(bytes, Base64.DEFAULT));
//开辟线程访问服务端,将imgStr传给服务器
AsyncHttpClient client = new AsyncHttpClient();
RequestParams params = new RequestParams();
params.add("imgStr", imgStr);
client.post("填写服务端的地址", params,new AsyncHttpResponseHandler() {
@Override
public void onSuccess(int arg0, Header[] arg1, byte[] arg2) {
// TODO Auto-generated method stub
}
@Override
public void onFailure(int arg0, Header[] arg1, byte[] arg2, Throwable arg3) {
// TODO Auto-generated method stub
}
});
}
private void getCamera(Intent data) {
// 调用相机拍图片
if(data == null)
{
return;
}else{
Bundle cameraBundle = data.getExtras();
if(cameraBundle!=null){
Bitmap cameraBitmap = cameraBundle.getParcelable("data");
File tmpDir = new File(Environment.getExternalStorageDirectory()+ "/picture.");
if(!tmpDir.exists())
{
tmpDir.mkdir();
}
File realImg = new File(tmpDir.getAbsolutePath() + "avater2.jpg");
try {
FileOutputStream fos = new FileOutputStream(realImg);
cameraBitmap.compress(Bitmap.CompressFormat.JPEG, 85, fos);
fos.flush();
fos.close();
Uri cameraFromFile = Uri.fromFile(realImg);
//裁剪图片
cropPicture(cameraFromFile, 1, 1, 120, 120, SELECT_CAMERA);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
private void getPicture(Intent data) {
// 从相册中获取照片
if (data == null) {
return;
} else {
// 获取相册图片的uri
Uri galleryUri = data.getData();
try {
// 将地址中的图片读取为galleryBitmap
InputStream is = getContentResolver().openInputStream(
galleryUri);
Bitmap galleryBitmap = BitmapFactory.decodeStream(is);
is.close();
// 储存galleryBitmap并提供uri地址:
File tmpDir = new File(
Environment.getExternalStorageDirectory()
+ "/picture.");
Log.e("hxy", tmpDir.getAbsolutePath() + "");
if (!tmpDir.exists()) {
tmpDir.mkdir();
}
File galleryFile = new File(tmpDir.getAbsolutePath()
+ "avater.jpg");
Log.e("hxy", galleryFile.getName() + "");
// 压缩图片
FileOutputStream fos = new FileOutputStream(galleryFile);
galleryBitmap.compress(Bitmap.CompressFormat.JPEG, 85, fos);
fos.flush();
fos.close();
Uri galleryfromFile = Uri.fromFile(galleryFile);
// 裁剪图片
cropPicture(galleryfromFile, 8, 3, 480, 120, SELECT_PICTURE);
} catch (Exception e) {
e.printStackTrace();
}
}
}
private void cropPicture(Uri uri, int scaleX, int scaleY, int outputX,
int outputY, int requestCode) {
Intent intent = new Intent("com.android.camera.action.CROP");
intent.setDataAndType(uri, "image/*");
intent.putExtra("crop", "true");
intent.putExtra("aspectX", scaleX);
intent.putExtra("aspectY", scaleY);
intent.putExtra("outputX", outputX);
intent.putExtra("outputY", outputY);
intent.putExtra("return-data", true);
if (requestCode == SELECT_PICTURE) {
startActivityForResult(intent, CROP_IMAGE1);
} else {
startActivityForResult(intent, CROP_IMAGE2);
}
}
}
其中上传服务器的代码的实现需要根据具体需求来实现。