使用Android MediaStore裁剪大图片初次探究
来源:互联网 发布:战舰少女r重炮改数据 编辑:程序博客网 时间:2024/05/17 03:55
这篇文章相当经典而实用,想当初我做手机拍照截图的时候,大多都是在网上抄来抄去的内容,从来没有人考虑过实际项目中的需求。实际上,拍照传大图片,如果用普通方式会耗用极大的内存,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:
附加选项数据类型描述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的源码片段:
// 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. */
@Override
public
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
;
}
@Override
protected
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
;
}
2 0
- 使用Android MediaStore裁剪大图片初次探究
- 如何使用Android MediaStore裁剪大图片
- 如何使用Android MediaStore裁剪大图片
- 如何使用Android MediaStore裁剪大图片
- 如何使用Android MediaStore裁剪大图片
- 如何使用Android MediaStore裁剪大图片
- 如何使用Android MediaStore裁剪大图片
- 如何使用Android MediaStore裁剪大图片
- 如何使用Android MediaStore裁剪大图片
- 如何使用Android MediaStore裁剪大图片
- 【译】如何使用Android MediaStore裁剪大图片
- 【译】如何使用Android MediaStore裁剪大图片
- 【译】如何使用Android MediaStore裁剪大图片
- 【译】如何使用Android MediaStore裁剪大图片
- 【译】如何使用Android MediaStore裁剪大图片
- 【译】如何使用Android MediaStore裁剪大图片
- 4.14-2 如何使用Android MediaStore裁剪大图片
- 【译】如何使用Android MediaStore裁剪大图片
- 手机端链接点击是会出现边框
- 在拼接的字符串中根据代码显示名称
- Maven简介(三)——profile介绍
- LUA中的正则表达式
- Java之List
- 使用Android MediaStore裁剪大图片初次探究
- 函数的变量类型
- verliog中有reg[7:0] mem[0:255]的写法,那么这跟直接用一个RAM有什么区别
- Jump Game II
- Xcode6制作动态及静态Framework
- Ext JS4.2 实现点击按钮弹出window框
- cocos2dx-3.x学习笔记二:随机数的生成及注意问题
- MYSQL 分组并查询最大时间
- iOS官方Sample大全