最近做android拍照上传图片到服务器,遇到拍照后获取的图片被旋转的问题。
百度了一些资料,加上自己研究了一天终于得到解决。
1. 调用系统照相机
private originalImagePath = null;
private void callCamera() {
// call the system Camera
//普通做法
//Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
//startActivityForResult(cameraIntent, CALL_CAMERA_REQUEST_CODE);
// 处理后的做法
File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "escooter/camera");
if (!file.exists()) {
file.mkdir();
}
String dir = file.getAbsolutePath();
String filePath = dir + "/" + System.currentTimeMillis() + ".jpg";
File f = new File(filePath);
originalImagePath = f.getAbsolutePath(); // 指定路径, 将在onActivityResult中使用
Uri u = Uri.fromFile(f);
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, u); // 指定拍照后的照片的保存路径, 保存的是原图
startActivityForResult(cameraIntent, CALL_CAMERA_REQUEST_CODE); // 这种做法有的手机获取的data为null
}
2. 处理照片
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
Log.d("tag", "requestCode=" + requestCode + "; resultCode=" + resultCode
+ "; data=" + data + "; originalImagePath=" + originalImagePath);
// 这里data为null, 不过没关系, 继续处理
if (resultCode == Activity.RESULT_OK) {
if (requestCode == CALL_CAMERA_REQUEST_CODE) {
Bitmap bitmap = BitmapFactory.decodeFile(originalImagePath);
if (bitmap == null) return;
String finalPath = null; // 处理后的照片路径
// 获取照片旋转的度数,
int degree = getBitmapDegree(originalImagePath);
if (degree != 0) { // 表示照片旋转了
bitmap = PicCache.rotateBitmapByDegree(bitmap, degree); // 将照片转正
saveBitmapFromCamera(bitmap, bitmap.toString()); // 将转正后的照片保存, 这就是我们要用的照片
File filea = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES), "escooter/camera");
finalPath = filea.getAbsolutePath() + "/" + bitmap.toString().hashCode() + ".jpg";
} else {
finalPath = originalImagePath;
}
}
}
}
3. finalPath 就是我们最终处理后的照片的路径, 上传图片的时候使用这个路径即可. 怎么上传图片看我另一篇博客http://blog.csdn.net/likesidehu/article/details/52794890
4. 另外用到的两个方法, 网上找的
public int getBitmapDegree(String path) {
int degree = 0;
try {
// 从指定路径下读取图片,并获取其EXIF信息
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();
}
Log.d("tag", "degree=" + degree);
return degree;
}
//将图片按照某个角度进行旋转
public Bitmap rotateBitmapByDegree(Bitmap bm, int degree) {
Bitmap returnBm = null;
// 根据旋转角度,生成旋转矩阵
Matrix matrix = new Matrix();
matrix.postRotate(degree);
try {
// 将原始图片按照旋转矩阵进行旋转,并得到新的图片
returnBm = Bitmap.createBitmap(bm, 0, 0, bm.getWidth(), bm.getHeight(), matrix, true);
} catch (OutOfMemoryError e) {
Log.d("tag", "rotate bitmap exception:" + e);
}
if (returnBm == null) {
returnBm = bm;
}
if (bm != returnBm) {
bm.recycle();
}
return returnBm;
}
5. 有的手机拍照的照片很大, 上传的时候压力山大, 这个方法是将图片按比例压缩不失真并保存到本地
public static void saveBitmapFromCamera(Bitmap bmp, String name) {
if (!isSdcardExisted()) return;
if (bmp == null || name == null) return;
int bWidth = bmp.getWidth();
int bHeight = bmp.getHeight();
int SIZE = 100;
final int WIDTH = 1920;
final int HEIGHT = 1080;
if (bWidth > WIDTH || bHeight > HEIGHT) {
SIZE = 50;
}
File file = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES), "escooter/camera");
if (!file.mkdirs()) {
Log.e("tag", "Directory not created :" + file.exists());
}
if (file == null) {
return;
}
String path = file.getAbsolutePath();
File f = new File(path + "/" + name.hashCode() + ".jpg");
if (!f.exists()) {
try {
f.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
} else {
return;
}
try {
FileOutputStream out = new FileOutputStream(f);
bmp.compress(Bitmap.CompressFormat.JPEG, SIZE, out);
out.flush();
out.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}