一、主要的几个压缩方式
二、相机的使用
三、相关权限
四、图片的旋转角度
五、图片的基本信息
/**
* 保存图片时压缩
*
* @param bmp
* @param file
*/
public static void compressBmpToFile(Bitmap bmp, File file) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int options = 80;
bmp.compress(Bitmap.CompressFormat.JPEG, options, baos);
while (baos.toByteArray().length / 1024 > 1000) {
baos.reset();
options -= 1;
bmp.compress(Bitmap.CompressFormat.JPEG, options, baos);
}
try {
FileOutputStream fos = new FileOutputStream(file);
fos.write(baos.toByteArray());
fos.flush();
fos.close();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 按比例压缩图片
*
* @param srcPath
* @param hh
* @param ww
* @return
*/
private Bitmap compressImageFromFile(String srcPath, float hh, float ww) {
BitmapFactory.Options newOpts = new BitmapFactory.Options();
newOpts.inJustDecodeBounds = true;//只读边,不读内容
Bitmap bitmap = BitmapFactory.decodeFile(srcPath, newOpts);
newOpts.inJustDecodeBounds = false;
int w = newOpts.outWidth;
int h = newOpts.outHeight;
int be = 1;
if (w > h && w > ww) {
be = (int) (newOpts.outWidth / ww);
} else if (w < h && h > hh) {
be = (int) (newOpts.outHeight / hh);
}
if (be <= 0)
be = 1;
newOpts.inSampleSize = be;//设置采样率
newOpts.inPreferredConfig = Bitmap.Config.ARGB_8888;//该模式是默认的,可不设
newOpts.inPurgeable = true;// 同时设置才会有效
newOpts.inInputShareable = true;//。当系统内存不够时候图片自动被回收
bitmap = BitmapFactory.decodeFile(srcPath, newOpts);
// return compressBmpFromBmp(bitmap);//原来的方法调用了这个方法企图进行二次压缩
//其实是无效的,大家尽管尝试
return bitmap;
}
二、相机的使用
//弹出选择框
protected void createSelectImageDialog() {
CharSequence[] items = {"相册", "照相机"};
new AlertDialog.Builder(this).setTitle("选择图片来源").setItems(items,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
if (which == SELECT_PICTURE) {
Intent intent = new Intent();
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
intent.setAction(Intent.ACTION_GET_CONTENT);
} else {
intent.setAction(Intent.ACTION_OPEN_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
}
intent.setType("image/*");
startActivityForResult(Intent.createChooser(intent, "选择图片"),
CONSULT_DOC_PICTURE);
} else {
String status = Environment.getExternalStorageState();
if (status.equals(Environment.MEDIA_MOUNTED)) {//判断是否有SD卡
doTakePhoto();
} else {
showToast("没有SD卡");
}
}
}
}).create().show();
}
/**
* 拍照获取图片
*/
protected void doTakePhoto() {
try {
// Launch camera to take photo for selected contact
PHOTO_DIR.mkdirs();// 创建照片的存储目录
mCurrentPhotoFile = new File(PHOTO_DIR, getPhotoFileName());// 给新照的照片文件命名
final Intent intent = getTakePickIntent(mCurrentPhotoFile);
startActivityForResult(intent, CONSULT_DOC_CAMERA);
} catch (ActivityNotFoundException e) {
showToast("照片不存在");
}
}
public static Intent getTakePickIntent(File f) {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE, null);
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(f));
return intent;
}
三、相关权限
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
<uses-feature android:name="android.hardware.camera" />
四、图片的旋转角度
/**
* 获取图片的旋转角度
*
* @param filepath
* @return
*/
public static int getExifOrientation(String filepath) {
int degree = 0;
ExifInterface exif = null;
try {
exif = new ExifInterface(filepath);
} catch (IOException ex) {
}
if (exif != null) {
int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, -1);
if (orientation != -1) {
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;
}
}
}
return degree;
}
五、图片的基本信息
private Map<String, String> mapDetails;
private void showImageDetails() {
Cursor cursor = null;
String column = MediaStore.Images.ImageColumns.DATA;
try {
cursor = getContentResolver().query(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI, null,
column + "=?", new String[]{tempImagePath}, null);
if (cursor != null && cursor.moveToFirst()) {
mapDetails = new LinkedHashMap<String, String>();
mapDetails
.put("title",
cursor.getString(cursor
.getColumnIndex(MediaStore.Images.Media.DISPLAY_NAME)));
SimpleDateFormat sdf = new SimpleDateFormat(
"yyyy-MM-dd HH-mm-ss"); // 实例化模板对象
try {
Date times = sdf
.parse(cursor.getString(cursor
.getColumnIndex(MediaStore.Images.Media.DATE_ADDED)));
mapDetails.put("times",
String.valueOf(times));
} catch (ParseException e1) {
e1.printStackTrace();
}
mapDetails
.put("description",
cursor.getString(cursor
.getColumnIndex(MediaStore.Images.Media.DESCRIPTION)));
int fileSize = Integer.parseInt(cursor.getString(cursor
.getColumnIndex(MediaStore.Images.Media.SIZE)));
mapDetails.put("file_size",
formatFileSize(fileSize));
mapDetails
.put("mimetype",
cursor.getString(cursor
.getColumnIndex(MediaStore.Images.Media.MIME_TYPE)));
mapDetails
.put("height",
cursor.getString(cursor
.getColumnIndex(MediaStore.Images.Media.HEIGHT)));
mapDetails
.put("width", cursor.getString(cursor
.getColumnIndex(MediaStore.Images.Media.WIDTH)));
int degree = getExifOrientation(tempImagePath);
mapDetails.put("degree", degree + "");
}
} finally {
if (cursor != null)
cursor.close();
}
text_big.setText(detailsToString());
}
六、运行截图:
备注:遇到的问题
1、使用相机时,点击确定按钮,无反应。点击返回时,能获取到照相所得的图片 uri
有时候我们会发现用相机拍摄获取照片的时候,得到的 uri 是 null 的,这是因为android把拍摄的图片封装到bundle中传递回来,但是根据不同的机器获得相片的方式不太一样,可能有的相机能够通过inten.getData()获取到uri, 然后再根据uri获取数据的路径,在封装成bitmap,但有时候有的相机获取到的是null的,这时候我们该怎么办呢?
其实这时候我们就应该从bundle中获取数据,通过 (Bitmap) bundle.get("data")获取到相机图片的bitmap数据。
2、下面是选择相册时,日志台中输出的错误,求解答???
0-29 17:54:48.509 30013-30013/demo.my.com.myapidemo E/ActivityThread﹕ Activity com.android.internal.app.ChooserActivity has leaked IntentReceiver
com.android.internal.app.ResolverActivity$1@41810fc8 that was originally registered here. Are you missing a call to unregisterReceiver()?
android.app.IntentReceiverLeaked: Activity com.android.internal.app.ChooserActivity has leaked IntentReceiver
com.android.internal.app.ResolverActivity$1@41810fc8 that was originally registered h
参考链接:http://blog.youkuaiyun.com/cherry609195946/article/details/9264409