Android MediaStore裁剪图片1

来源:互联网 发布:淘宝全网举报链接 编辑:程序博客网 时间:2024/05/01 08:02

译文:

 概述

          我写这篇文章是为了发表我对MediaStore裁剪图片功能的一些简要研究。基本上,如果你要写一个应用程序,使用已有的Media Gallery并允许用户在你的应用里选取TA的图片的一部分(可选功能:人脸识别)。 可以使用一个Intent做到这个,但是也存在着相应的问题,总的来说也缺少这方面的文档告诉我们怎么实现它。 另外,这篇文章基于2.1并且在Nexus One上做了测试。 Nexus One上的实现似乎被这群人写在了这里: Media Gellery for Nexus One  

 反馈

         这篇文章需要使用基于我的研究所写的程序。如果你对我推荐的实现方案有所改进,请让我知道。我会相应的更新这篇文章。 

Intent细节

        首先,让我们探讨下Intent以及它的特点。在看了一些代码示例以后,我发现我可以很轻松的使用如下的Intent调用裁剪功能: 
Intent intent = new Intent(Intent.ACTION_GET_CONTENT, null);  intent.setType(“image/*”); intent.putExtra(“crop”, “true”);
 然而,这是在我缺少附加的文档,不知道这些选项的具体含义等等情况之下的选择。所以,我将我的yanj整理成一个表格 ,并写了一个演示程序,力图演示控制此功能的所有可供选项。 
你可以在你的程序中使用使用我的代码,并且扩展它。我会将之附加在这篇文章上。 
Exta Options Table for image/* crop:附加选项数据类型描述cropString发送裁剪信号aspectXintX方向上的比例aspectYintY方向上的比例outputXint裁剪区的宽outputYint裁剪区的高scaleboolean是否保留比例return-databoolean是否将数据保留在Bitmap中返回dataParcelable相应的Bitmap数据circleCropString圆形裁剪区域?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的源码片段: 

1// Return the cropped image directly or save it to the specified URI.
2Bundle myExtras = getIntent().getExtras();
3if (myExtras != null && (myExtras.getParcelable("data") != null|| myExtras.getBoolean("return-data")))
4{
5    Bundle extras = new Bundle();
6    extras.putParcelable("data", croppedImage);
7    setResult(RESULT_OK,(new Intent()).setAction("inline-data").putExtras(extras));
8    finish();
9}方法2: 如果你将return-data设置为“false”,那么在onActivityResult的Intent数据中你将不会接收到任何Bitmap,相反,你需要将MediaStore.EXTRA_OUTPUT关联到一个Uri,此Uri是用来存放Bitmap的。 

但是还有一些条件,首先你需要有一个短暂的与此Uri相关联的文件地址,当然这不是个大问题(除非是那些没有sdcard的设备)。

         下面是CropImage.java关于操作Uri的源码片段: 

01if (mSaveUri != null) {
02    OutputStream outputStream = null;
03    try {
04        outputStream = mContentResolver.openOutputStream(mSaveUri);
05        if (outputStream != null) {
06            croppedImage.compress(mOutputFormat, 75, outputStream);
07        }
08    catch (IOException ex) {
09        // TODO: report error to caller
10        Log.e(TAG, "Cannot open file: " + mSaveUri, ex);
11    finally {
12        Util.closeSilently(outputStream);
13    }
14    Bundle extras = new Bundle();
15    setResult(RESULT_OK, new Intent(mSaveUri.toString()).putExtras(extras));
16}

代码示例:

        我已经附上了一些代码示例,应该可以让你测试多种配置。请让我知道它对你是否有用。

代码下载: MediaStoreTest 
view source
print?
01/** Called when the activity is first created. */
02@Override
03public void onCreate(Bundle savedInstanceState) {
04    super.onCreate(savedInstanceState);
05    thiz = this;
06    setContentView(R.layout.main);
07    mBtn = (Button) findViewById(R.id.btnLaunch);
08    photo = (ImageView) findViewById(R.id.imgPhoto);
09    mBtn.setOnClickListener(new OnClickListener() {
10 
11        public void onClick(View v) {
12            try {
13                // Launch picker to choose photo for selected contact
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;">                                 // lol, negative boolean noFaceDetection</span> intent.putExtra("noFaceDetection", !faceDetection);
26                if (circleCrop) {
27                    intent.putExtra("circleCrop"true);
28                }
29 
30                startActivityForResult(intent, PHOTO_PICKED);
31            catch (ActivityNotFoundException e) {
32                Toast.makeText(thiz, R.string.photoPickerNotFoundText,
33                        Toast.LENGTH_LONG).show();
34            }
35        }
36    });
37 
38}
39 
40private Uri getTempUri() {
41    return Uri.fromFile(getTempFile());
42}
43 
44private File getTempFile() {
45    if (isSDCARDMounted()) {
46 
47        File f = new File(Environment.getExternalStorageDirectory(),
48                TEMP_PHOTO_FILE);
49        try {
50            f.createNewFile();
51        catch (IOException e) {
52            // TODO Auto-generated catch block
53            Toast.makeText(thiz, R.string.fileIOIssue, Toast.LENGTH_LONG)
54                    .show();
55        }
56        return f;
57    else {
58        return null;
59    }
60}
61 
62private boolean isSDCARDMounted() {
63    String status = Environment.getExternalStorageState();
64 
65    if (status.equals(Environment.MEDIA_MOUNTED))
66        return true;
67    return false;
68}
69 
70@Override
71protected void onActivityResult(int requestCode, int resultCode, Intent data) {
72    super.onActivityResult(requestCode, resultCode, data);
73 
74    switch (requestCode) {
75    case PHOTO_PICKED:
76        if (resultCode == RESULT_OK) {
77            if (data == null) {
78                Log.w(TAG, "Null data, but RESULT_OK, from image picker!");
79                Toast t = Toast.makeText(this, R.string.no_photo_picked,
80                        Toast.LENGTH_SHORT);
81                t.show();
82                return;
83            }
84 
85            final Bundle extras = data.getExtras();
86            if (extras != null) {
87                File tempFile = getTempFile();
88                // new logic to get the photo from a URI
89                if (data.getAction() != null) {
90                    processPhotoUpdate(tempFile);
91                }
92            }
93        }
94        break;
95    }
96}

0 0
原创粉丝点击