转自:http://blog.youkuaiyun.com/floodingfire/article/details/8144604
首先,让我们探讨下Intent以及它的特点。在看了一些代码示例以后,我发现我可以很轻松的使用如下的Intent调用裁剪功能:
1 | Intent intent = new Intent(Intent.ACTION_GET_CONTENT, null ); |
2 | intent.setType(“image/*”); |
3 | intent.putExtra(“crop”, “ true ”); |
然而,这是在我缺少附加的文档,不知道这些选项的具体含义等等情况之下的选择。所以,我将我的yanj整理成一个表格 ,并写了一个演示程序,力图演示控制此功能的所有可供选项。
你可以在你的程序中使用使用我的代码,并且扩展它。我会将之附加在这篇文章上。
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:///...,详见代码示例 |
现在,最令人困惑的是MediaStore.EXTRA_OUTPUT以及return-data选项。
你主要有两种方式从这个Intent中取得返回的bitmap:获取内部数据或者提供一个Uri以便程序可以将数据写入。
方法1:如果你将return-data设置为“true”,你将会获得一个与内部数据关联的Action,并且bitmap以此方式返回:(Bitmap)extras.getParcelable("data")。注意:如果你最终要获取的图片非常大,那么此方法会给你带来麻烦,所以你要控制outputX和outputY保持在较小的尺寸。鉴于此原因,在我的代码中没有使用此方法((Bitmap)extras.getParcelable("data"))。
下面是CropImage.java的源码片段:
2 | Bundle myExtras = getIntent().getExtras(); |
3 | if (myExtras != null && (myExtras.getParcelable( "data" ) != null || myExtras.getBoolean( "return-data" ))) |
5 | Bundle extras = new Bundle(); |
6 | extras.putParcelable( "data" , croppedImage); |
7 | setResult(RESULT_OK,( new Intent()).setAction( "inline-data" ).putExtras(extras)); |
方法2:
如果你将return-data设置为“false”,那么在onActivityResult的Intent数据中你将不会接收到任何Bitmap,相反,你需要将MediaStore.EXTRA_OUTPUT关联到一个Uri,此Uri是用来存放Bitmap的。
但是还有一些条件,首先你需要有一个短暂的与此Uri相关联的文件地址,当然这不是个大问题(除非是那些没有sdcard的设备)。
下面是CropImage.java关于操作Uri的源码片段:
01 | if (mSaveUri != null ) { |
02 | OutputStream outputStream = null ; |
04 | outputStream = mContentResolver.openOutputStream(mSaveUri); |
05 | if (outputStream != null ) { |
06 | croppedImage.compress(mOutputFormat, 75 , outputStream); |
08 | } catch (IOException ex) { |
10 | Log.e(TAG, "Cannot open file: " + mSaveUri, ex); |
12 | Util.closeSilently(outputStream); |
14 | Bundle extras = new Bundle(); |
15 | setResult(RESULT_OK, new Intent(mSaveUri.toString()).putExtras(extras)); |
代码示例:
我已经附上了一些代码示例,应该可以让你测试多种配置。请让我知道它对你是否有用。
代码下载:
MediaStoreTest
01 | /** Called when the activity is first created. */ |
03 | public void onCreate(Bundle savedInstanceState) { |
04 | super .onCreate(savedInstanceState); |
06 | setContentView(R.layout.main); |
07 | mBtn = (Button) findViewById(R.id.btnLaunch); |
08 | photo = (ImageView) findViewById(R.id.imgPhoto); |
09 | mBtn.setOnClickListener( new OnClickListener() { |
11 | public void onClick(View v) { |
14 | Intent intent = new Intent(Intent.ACTION_GET_CONTENT, null ); |
15 | intent.setType( "image/*" ); |
16 | intent.putExtra( "crop" , "true" ); |
17 | intent.putExtra( "aspectX" , aspectX); |
18 | intent.putExtra( "aspectY" , aspectY); |
19 | intent.putExtra( "outputX" , outputX); |
20 | intent.putExtra( "outputY" , outputY); |
21 | intent.putExtra( "scale" , scale); |
22 | intent.putExtra( "return-data" , return_data); |
23 | intent.putExtra(MediaStore.EXTRA_OUTPUT, getTempUri()); |
24 | intent.putExtra( "outputFormat" , |
25 | Bitmap.CompressFormat.JPEG.toString()); <span style= "color:#48465A;font-family:monospace;font-size:11px;line-height:normal;background-color:#EFEFEF;" > |
27 | intent.putExtra( "circleCrop" , true ); |
30 | startActivityForResult(intent, PHOTO_PICKED); |
31 | } catch (ActivityNotFoundException e) { |
32 | Toast.makeText(thiz, R.string.photoPickerNotFoundText, |
33 | Toast.LENGTH_LONG).show(); |
40 | private Uri getTempUri() { |
41 | return Uri.fromFile(getTempFile()); |
44 | private File getTempFile() { |
45 | if (isSDCARDMounted()) { |
47 | File f = new File(Environment.getExternalStorageDirectory(), |
51 | } catch (IOException e) { |
53 | Toast.makeText(thiz, R.string.fileIOIssue, Toast.LENGTH_LONG) |
62 | private boolean isSDCARDMounted() { |
63 | String status = Environment.getExternalStorageState(); |
65 | if (status.equals(Environment.MEDIA_MOUNTED)) |
71 | protected void onActivityResult( int requestCode, int resultCode, Intent data) { |
72 | super .onActivityResult(requestCode, resultCode, data); |
74 | switch (requestCode) { |
76 | if (resultCode == RESULT_OK) { |
78 | Log.w(TAG, "Null data, but RESULT_OK, from image picker!" ); |
79 | Toast t = Toast.makeText( this , R.string.no_photo_picked, |
85 | final Bundle extras = data.getExtras(); |
87 | File tempFile = getTempFile(); |
89 | if (data.getAction() != null ) { |
90 | processPhotoUpdate(tempFile); |