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

android 根据uri获取路径及图片压缩、旋转的学习笔记

2015-04-23 16:49 525 查看
<span style="font-family: Arial, Helvetica, sans-serif;">做项目用到了这些,根据uri取得图片或视频的路径,上传拍摄的照片,遇到的一些问题:</span>


1. 4.4以前和以后(含4.4)的URI格式不一样

2. 拍照后返回的URI有可能为null

3. 拍照后的图片有可能有旋转

一:URI格式问题

4.4以前:
Uri
: content:
//media/extenral/images/media/17766


4.4及以后:
content:
//com.android.providers.media.documents/document/image%2706


解决,用一下的工具类即可解决此问题,此工具类兼顾了4.4以前及以后的版本,亲测可用:

@SuppressLint("NewApi")
public static String getPath(final Context context, final Uri uri) {

final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;

// DocumentProvider
if (isKitKat && DocumentsContract.isDocumentUri(context, uri)){
// ExternalStorageProvider
if (isExternalStorageDocument(uri)){
final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
final String type = split[0];

if ("primary".equalsIgnoreCase(type)){
return Environment.getExternalStorageDirectory() + "/" + split[1];
}
}
// DownloadsProvider
else if (isDownloadsDocument(uri)){

final String id = DocumentsContract.getDocumentId(uri);
final Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));

return getDataColumn(context, contentUri, null, null);
}
// MediaProvider
else if (isMediaDocument(uri)){
final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
final String type = split[0];

Uri contentUri = null;
if ("image".equals(type)){
contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
}
else if ("video".equals(type)){
contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
}
else if ("audio".equals(type)){
contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
}

final String selection = "_id=?";
final String[] selectionArgs = new String[] { split[1] };

return getDataColumn(context, contentUri, selection, selectionArgs);
}
}
// MediaStore (and general)
else if ("content".equalsIgnoreCase(uri.getScheme())){
return getDataColumn(context, uri, null, null);
}
// File
else if ("file".equalsIgnoreCase(uri.getScheme())){
return uri.getPath();
}

return null;
}

/**
* Get the value of the data column for this Uri. This is useful for
* MediaStore Uris, and other file-based ContentProviders.
* @param context The context.
* @param uri The Uri to query.
* @param selection (Optional) Filter used in the query.
* @param selectionArgs (Optional) Selection arguments used in the query.
* @return The value of the _data column, which is typically a file path.
*/
public static String getDataColumn(Context context, Uri uri, String selection, String[] selectionArgs) {

Cursor cursor = null;
final String column = "_data";
final String[] projection = { column };

try{
cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null);
if (cursor != null && cursor.moveToFirst()){
final int column_index = cursor.getColumnIndexOrThrow(column);
return cursor.getString(column_index);
}
} finally{
if (cursor != null)
cursor.close();
}
return null;
}

/**
* @param uri  The Uri to check.
* @return Whether the Uri authority is ExternalStorageProvider.
*/
public static boolean isExternalStorageDocument(Uri uri) {
return "com.android.externalstorage.documents".equals(uri.getAuthority());
}

/**
* @param uri  The Uri to check.
* @return Whether the Uri authority is DownloadsProvider.
*/
public static boolean isDownloadsDocument(Uri uri) {
return "com.android.providers.downloads.documents".equals(uri.getAuthority());
}

/**
* @param uri The Uri to check.
* @return Whether the Uri authority is MediaProvider.
*/
public static boolean isMediaDocument(Uri uri) {
return "com.android.providers.media.documents".equals(uri.getAuthority());
}


二、拍照后返回的uri为null

有些机型调用拍照后返回的data为空或取得的uri为null,解决思路:自己构造一个uri,判断获取的uri是否为空,若为空则赋值给它。

首先,调用一下程序进行拍照:

<span style="white-space:pre">	</span>Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
SimpleDateFormat timeStampFormat = new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss");
String filename = timeStampFormat.format(new Date());
ContentValues values = new ContentValues();
values.put(Media.TITLE, filename);
photoUri = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values); //在程序里定义的变量
intent.putExtra(MediaStore.EXTRA_OUTPUT, photoUri);
startActivityForResult(intent, PAIZHAO);


在onActivityResult里面进行处理:

Uri uri = null;
if (data != null && data.getData() != null){
uri = data.getData();
}
// 一些机型无法从getData中获取uri,则需手动指定拍照后存储照片的Uri
if (uri == null){
if (photoUri != null){
uri = photoUri;
}
}


然后调用开始介绍的工具类即可取得图片的路径。

三、拍照后图片有旋转

有一些手机拍照后图片会有旋转,上传到服务器后显示会有问题。

解决思路,先获取图片选择角度:

// 判断照片角度
public static int readPictureDegree(String path) {
int degree = 0;
try{
ExifInterface exifInterface = new ExifInterface(path);
int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
switch (orientation) {
case ExifInterface.ORIENTATION_ROTATE_90:
degree = 90;
break;
case ExifInterface.ORIENTATION_ROTATE_180:
degree = 180;
break;
case ExifInterface.ORIENTATION_ROTATE_270:
degree = 270;
break;
}
} catch (IOException e){
e.printStackTrace();
}
return degree;
}
然后进行旋转:

// 旋转照片
public static Bitmap rotateBitmap(Bitmap bitmap, int degress) {
if (bitmap != null){
Matrix m = new Matrix();
m.postRotate(degress);
bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), m, true);
return bitmap;
}
return bitmap;
}


利用下面的语句可对图像进行压缩:

File outputFile = new File(filePath);
FileOutputStream out = new FileOutputStream(outputFile);
bm.compress(Bitmap.CompressFormat.JPEG, q, out); //q为压缩率,0-100,越小图像压缩后质量越小,一般30以上不失真
//outputFile.getPath();可获取路径


-------------------------------------------------------------------------------------------------------------------------

以上内容非原创,是对网上内容的一个总结。

参考:
http://www.2cto.com/kf/201502/376975.html http://blog.sina.com.cn/s/blog_4c7d14600101jhaf.html http://blog.csdn.net/leechee_1986/article/details/25049243
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐