您的位置:首页 > 移动开发 > Android开发

图片裁剪问题

2015-12-01 11:04 387 查看
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:///...,详见代码示例
测试的简化代码





1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
2     xmlns:tools="http://schemas.android.com/tools"
3     android:layout_width="match_parent"
4     android:layout_height="match_parent"
5     tools:context=".MainActivity" >
6
7     <Button
8         android:id="@+id/button"
9         android:layout_width="wrap_content"
10         android:layout_height="wrap_content"
11         android:text="click me!" />
12
13     <ImageView
14         android:id="@+id/imageview"
15         android:layout_width="match_parent"
16         android:layout_height="match_parent"
17         android:scaleType="centerInside" />
18
19 </LinearLayout>









1 public class MainActivity extends Activity implements OnClickListener {
2
3     private Uri imageUri;
4     private static final String IMAGE_FILE_LOCATION = "file:///sdcard/temp.jpg";
5     private Button btn;
6     private ImageView iv;
7
8     @Override
9     protected void onCreate(Bundle savedInstanceState) {
10         super.onCreate(savedInstanceState);
11         setContentView(R.layout.activity_main);
12         btn = (Button) findViewById(R.id.button);
13         btn.setOnClickListener(this);
14         imageUri = Uri.parse(IMAGE_FILE_LOCATION);
15         iv = (ImageView) findViewById(R.id.imageview);
16     }
17
18     @Override
19     public boolean onCreateOptionsMenu(Menu menu) {
20         // Inflate the menu; this adds items to the action bar if it is present.
21         getMenuInflater().inflate(R.menu.activity_main, menu);
22         return true;
23     }
24
25     @Override
26     public void onClick(View v) {
27         // TODO Auto-generated method stub
28
29         // 试着改成打开自己写的图片浏览器
30         switch (v.getId()) {
31         case R.id.button:
32             // 这段代码使用ACTION_GET_CONTENT和ACTION_PICK效果相同
33             Intent intent = new Intent(Intent.ACTION_GET_CONTENT, null);
34             // Intent intent = new Intent(Intent.ACTION_PICK, null);
35
36             // 如果使用com.android.camera.action.CROP 则直接打开裁剪照片的activity 那么可以用自己的图片浏览器选择图片 传入参数并使用之
37             // Intent intent = new Intent("com.android.camera.action.CROP");
38
39             // 如果不设置type,则 ACTION_GET_CONTENT 会弹出异常FATAL EXCEPTION:main android.content.ActivityNotFoundException
40             // 而 ACTION_PICK 会弹出可用程序列表 但没有打开图片相关的程序(在我的两个设备上是这样)
41             intent.setType("image/*");
42
43             // 设置在开启的Intent中设置显示的view可裁剪
44             // 这段代码里设置成false也能裁剪啊。。。这是为什么?懂的给我讲讲了
45             // 这段注释掉就不会跳转到裁剪的activity
46             intent.putExtra("crop", "true");
47
48             // 设置x,y的比例,截图方框就按照这个比例来截 若设置为0,0,或者不设置 则自由比例截图
49             intent.putExtra("aspectX", 2);
50             intent.putExtra("aspectY", 1);
51
52             // 裁剪区的宽和高 其实
e931
就是裁剪后的显示区域 若裁剪的比例不是显示的比例,则自动压缩图片填满显示区域。若设置为0,0 就不显示。若不设置,则按原始大小显示
53             intent.putExtra("outputX", 200);
54             intent.putExtra("outputY", 100);
55
56             // 不知道有啥用。。可能会保存一个比例值 需要相关文档啊
57             intent.putExtra("scale", true);
58
59             // true的话直接返回bitmap,可能会很占内存 不建议
60             intent.putExtra("return-data", false);
61             // 上面设为false的时候将MediaStore.EXTRA_OUTPUT即"output"关联一个Uri
62             intent.putExtra("output", imageUri);
63             // 看参数即可知道是输出格式
64             intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
65             // 面部识别 这里用不上
66             intent.putExtra("noFaceDetection", false);
67
68             // 想从Activity中获得返回数据,在启动Activity时候使用startActivityForResult方法
69             // 1为请求代码,可以是任意值,个人感觉用资源id会比较清楚,而且不会重复 比如当前控件的R.id.button
70             startActivityForResult(intent, 1);
71             break;
72         default:
73             break;
74         }
75     }
76
77     @Override
78     protected void onActivityResult(int requestCode, int resultCode, Intent data) {
79         // TODO Auto-generated method stub
80         super.onActivityResult(requestCode, resultCode, data);
81         if (resultCode != Activity.RESULT_OK) {// result is not correct
82             return;
83         } else {
84             switch (requestCode) {
85             case 1:
86                 if (imageUri != null) {
87                     Bitmap bitmap = decodeUriAsBitmap(imageUri);
88                     // 把解析到的位图显示出来
89                     iv.setImageBitmap(bitmap);
90                 }
91                 break;
92             default:
93                 break;
94             }
95
96         }
97     }
98
99     private Bitmap decodeUriAsBitmap(Uri uri) {
100         Bitmap bitmap = null;
101         try {
102             // 先通过getContentResolver方法获得一个ContentResolver实例,
103             // 调用openInputStream(Uri)方法获得uri关联的数据流stream
104             // 把上一步获得的数据流解析成为bitmap
105             bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(uri));
106         } catch (FileNotFoundException e) {
107             e.printStackTrace();
108             return null;
109         }
110         return bitmap;
111     }
112 }





使用裁剪功能用"com.android.camera.action.CROP"就可以。

传图片的话有两个方法,一个是intent直接传bitmap数据,另一个是传uri。

 





1     private void startCropIntent(String path) throws FileNotFoundException {
2         Bitmap bmp = BitmapFactory.decodeFile(path);
5         Intent intent = new Intent("com.android.camera.action.CROP"); 9         // Intent传输的bytes不能超过40k。不建议这样 无法处理大图
10         intent.putExtra("data", bmp);
11         // intent.setData(uri);
12         // intent.setType("image/*");
13         intent.setDataAndType(imageUri, "image/*");
14         intent.putExtra("crop", "true");
15         intent.putExtra("aspectX", 2);
16         intent.putExtra("aspectY", 1);
17         intent.putExtra("outputX", 300);
18         intent.putExtra("outputY", 150);
19         // 设置为true直接返回bitmap
20         intent.putExtra("return-data", true);
24         startActivityForResult(intent, 1);
25     }
26
27     @Override
28     protected void onActivityResult(int requestCode, int resultCode, Intent data) {
29         super.onActivityResult(requestCode, resultCode, data);
30         if (resultCode != Activity.RESULT_OK) {// result is not correct
31             return;
32         } else {
33             switch (requestCode) {
34             case 1:
40                 Bundle bundle = data.getExtras();
41                 Bitmap bitmap = bundle.getParcelable("data");
42                 iv.setImageBitmap(bitmap);
43
44                 break;
45
46             default:
47                 break;
48             }
49         }
51     }





这里参数path是选择的图片的绝对路径。

这种方法有局限性,因为intent传递的数据不超过40k,只能选择40k以下的图片裁剪

还是使用uri比较好





1 private void startCropIntent(String path) throws FileNotFoundException {
2         Bitmap bmp = BitmapFactory.decodeFile(path);
3
4         File file = new File(path);
5         Intent intent = new Intent("com.android.camera.action.CROP");
7         Uri uri = Uri.fromFile(file);// parse(pathUri);13         intent.setDataAndType(uri, "image/*");
14         intent.putExtra("crop", "true");
15         intent.putExtra("aspectX", 2);
16         intent.putExtra("aspectY", 1);
17         intent.putExtra("outputX", 300);
18         intent.putExtra("outputY", 150);
19         // 设置为true直接返回bitmap
20         intent.putExtra("return-data", false);
21         // 上面设为false的时候将MediaStore.EXTRA_OUTPUT关联一个Uri
22         intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
23         intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
24         startActivityForResult(intent, 1);
25     }
26
27     @Override
28     protected void onActivityResult(int requestCode, int resultCode, Intent data) {
29         super.onActivityResult(requestCode, resultCode, data);
30         if (resultCode != Activity.RESULT_OK) {// result is not correct
31             return;
32         } else {
33             switch (requestCode) {
34             case 1:
35                 if (imageUri != null) {
36                     Bitmap bitmap = decodeUriAsBitmap(imageUri);
37                     // 把解析到的位图显示出来
38                     iv.setImageBitmap(bitmap);
39                 }
44                 break;
45
46             default:
47                 break;
48             }
49         }
50
51     }
52
53     private Bitmap decodeUriAsBitmap(Uri uri) {
54         Bitmap bitmap = null;
55         try {
59             bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(uri));
60         } catch (FileNotFoundException e) {
61             e.printStackTrace();
62             return null;
63         }
64         return bitmap;
65     }





这里需要注意

intent.setData(uri);intent.setType("image/*");和

intent.setDataAndType(uri, "image/*");是有区别的。

我开始以为两个方法一样的,但看了源码就清楚了。

1  public Intent setDataAndType(Uri data, String type) {
2         mData = data;
3         mType = type;
4         return this;
5     }


1     public Intent setData(Uri data) {
2         mData = data;
3         mType = null;
4         return this;
5     }


1     public Intent setType(String type) {
2         mData = null;
3         mType = type;
4         return this;
5     }
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android