标签:
这篇文章相当经典而实用,想当初我做手机拍照截图的时候,大多都是在网上抄来抄去的内容,从来没有人考虑过实际项目中的需求。实际上,拍照传大图片,如果用普通方式会耗用极大的内存,Android一个App原则上的16M内存限制可以一下子被耗光。Android在拍照上有一个隐藏的设计,如果拍照图片过大,只返回一张缩略图。具体到不同手机,都是不一样的。
首先,让我们探讨下Intent以及它的特点。在看了一些代码示例以后,我发现我可以很轻松的使用如下的Intent调用裁剪功能:
Intent
intent = new
Intent(Intent.ACTION_GET_CONTENT, null);intent.setType(“image/*”);intent.putExtra(“crop”,
“true”);
Exta Options Table for image/* crop:
| 附加选项 | 数据类型 | 描述 |
| crop | String | 发送裁剪信号 |
| aspectX | int | X方向上的比例 |
| aspectY | int | Y方向上的比例 |
| outputX | int | 裁剪区的宽 |
| outputY | int | 裁剪区的高 |
| scale | boolean | 是否保留比例 |
| return-data | boolean | 是否将数据保留在Bitmap中返回 |
| data | Parcelable | 相应的Bitmap数据 |
| circleCrop | String | 圆形裁剪区域? |
| MediaStore.EXTRA_OUTPUT ("output") | URI | 将URI指向相应的file:///...,详见代码示例 |
你主要有两种方式从这个Intent中取得返回的bitmap:获取内部数据或者提供一个Uri以便程序可以将数据写入。
方法1:如果你将return-data设置为“true”,你将会获得一个与内部数据关联的Action,并且bitmap以此方式返回:(Bitmap)extras.getParcelable("data")。注意:如果你最终要获取的图片非常大,那么此方法会给你带来麻烦,所以你要控制outputX和outputY保持在较小的尺寸。鉴于此原因,在我的代码中没有使用此方法((Bitmap)extras.getParcelable("data"))。
下面是CropImage.java的源码片段:
//
Return the cropped image directly or save it to the specified URI.Bundle
myExtras = getIntent().getExtras();if
(myExtras != null
&& (myExtras.getParcelable("data")
!= null
|| myExtras.getBoolean("return-data"))){ Bundle
extras = new
Bundle(); extras.putParcelable("data",
croppedImage); setResult(RESULT_OK,(new
Intent()).setAction("inline-data").putExtras(extras)); finish();}
但是还有一些条件,首先你需要有一个短暂的与此Uri相关联的文件地址,当然这不是个大问题(除非是那些没有sdcard的设备)。
下面是CropImage.java关于操作Uri的源码片段:
f
(mSaveUri != null)
{ OutputStream
outputStream = null; try
{ outputStream
= mContentResolver.openOutputStream(mSaveUri); if
(outputStream != null)
{ croppedImage.compress(mOutputFormat,
75,
outputStream); } }
catch
(IOException ex) { //
TODO: report error to caller Log.e(TAG,
"Cannot
open file: "
+ mSaveUri, ex); }
finally
{ Util.closeSilently(outputStream); } Bundle
extras = new
Bundle(); setResult(RESULT_OK,
new
Intent(mSaveUri.toString()).putExtras(extras));}
/**
Called when the activity is first created. */@Overridepublic
void
onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); thiz
= this; setContentView(R.layout.main); mBtn
= (Button) findViewById(R.id.btnLaunch); photo
= (ImageView) findViewById(R.id.imgPhoto); mBtn.setOnClickListener(new
OnClickListener() { public
void
onClick(View v) { try
{ //
Launch picker to choose photo for selected contact Intent
intent = new
Intent(Intent.ACTION_GET_CONTENT, null); intent.setType("image/*"); intent.putExtra("crop",
"true"); intent.putExtra("aspectX",
aspectX); intent.putExtra("aspectY",
aspectY); intent.putExtra("outputX",
outputX); intent.putExtra("outputY",
outputY); intent.putExtra("scale",
scale); intent.putExtra("return-data",
return_data); intent.putExtra(MediaStore.EXTRA_OUTPUT,
getTempUri()); intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
<span style="color:#48465A;font-family:monospace;font-size:11px;line-height:normal;background-color:#EFEFEF;"> //
lol, negative boolean noFaceDetection</span> intent.putExtra("noFaceDetection", !faceDetection); if
(circleCrop) { intent.putExtra("circleCrop",
true); } startActivityForResult(intent,
PHOTO_PICKED); }
catch
(ActivityNotFoundException e) { Toast.makeText(thiz,
R.string.photoPickerNotFoundText, Toast.LENGTH_LONG).show(); } } });}private
Uri getTempUri() { return
Uri.fromFile(getTempFile());}private
File getTempFile() { if
(isSDCARDMounted()) { File
f = new
File(Environment.getExternalStorageDirectory(), TEMP_PHOTO_FILE); try
{ f.createNewFile(); }
catch
(IOException e) { //
TODO Auto-generated catch block Toast.makeText(thiz,
R.string.fileIOIssue, Toast.LENGTH_LONG) .show(); } return
f; }
else
{ return
null; }}private
boolean
isSDCARDMounted() { String
status = Environment.getExternalStorageState(); if
(status.equals(Environment.MEDIA_MOUNTED)) return
true; return
false;}@Overrideprotected
void
onActivityResult(int
requestCode, int
resultCode, Intent data) { super.onActivityResult(requestCode,
resultCode, data); switch
(requestCode) { case
PHOTO_PICKED: if
(resultCode == RESULT_OK) { if
(data == null)
{ Log.w(TAG,
"Null
data, but RESULT_OK, from image picker!"); Toast
t = Toast.makeText(this,
R.string.no_photo_picked, Toast.LENGTH_SHORT); t.show(); return; } final
Bundle extras = data.getExtras(); if
(extras != null)
{ File
tempFile = getTempFile(); //
new logic to get the photo from a URI if
(data.getAction() != null)
{ processPhotoUpdate(tempFile); } } } break; }标签:
原文地址:http://blog.csdn.net/qq_27073205/article/details/45248167