最近写Android的图片上传程序,测试的时候发现有些手机拍照后上传的是旋转了90度的照片(如我的魅族MX3手机),在网上找了好久,都没有真正解决,最后综合网上的方法,经过多次尝试,终于解决了。
拍照代码
private Uri photoUri;
String SDState = Environment.getExternalStorageState(); if(SDState.equals(Environment.MEDIA_MOUNTED)){ if(pictureInfos.size() < 8){ intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); ContentValues values = new ContentValues(); values.put(MediaStore.Images.Media.DISPLAY_NAME, String.valueOf(System.currentTimeMillis())+".jpg"); values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg"); photoUri = mContext.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values); intent.putExtra(MediaStore.Images.Media.ORIENTATION, 0); intent.putExtra(MediaStore.EXTRA_OUTPUT, photoUri); ((Activity)mContext).startActivityForResult(intent, ConstantUtils.CAPTURE_PHOTO); } else { Toast.makeText(mContext, mContext.getString(R.string.upload_pic_tip, 8), Toast.LENGTH_SHORT).show(); //提示 } }
onActivityResult代码
Cursor cursor = getContentResolver().query(photoUri, ConstantUtils.STORE_IMAGES, null, null, null);
PictureInfo pictureInfo = new PictureInfo(cursor.getString(3), cursor.getString(0), cursor.getString(1));
STORE_IMAGES代码
public static final String[] STORE_IMAGES = { MediaStore.Images.Media.DISPLAY_NAME,//显示的名字 MediaStore.Images.Media.DATA,//显示路径 MediaStore.Images.Media.LONGITUDE,//经度 MediaStore.Images.Media._ID,//id MediaStore.Images.Media.BUCKET_ID,//dir id 目录 MediaStore.Images.Media.BUCKET_DISPLAY_NAME,//dir name 目录名字 MediaStore.Images.Media.ORIENTATION };
PictureInfo代码
PictureInfo(String id, String photoName, String path)
上传代码
MultipartEntity entity = new MultipartEntity(); int orientation = PhotoUtils.readPictureDegree(pictureInfo.getUrl());//获取旋转角度 Bitmap bitmap = PhotoUtils.getimage(pictureInfo.getUrl());//压缩图片 if(Math.abs(orientation) > 0){ bitmap = PhotoUtils.rotaingImageView(orientation, bitmap);//旋转图片 } byte[] bytes = PhotoUtils.Bitmap2Bytes(bitmap);//生成二进制数据 ByteArrayInputStream baisi = new ByteArrayInputStream(bytes); entity.addPart(pictureInfo.getId(), new InputStreamBody(baisi, "image/jpeg", pictureInfo.getPhotoName()));
readPictureDegree代码
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; }
rotaingImageView代码
public static Bitmap rotaingImageView(int angle , Bitmap bitmap) { //旋转图片 动作 Matrix matrix = new Matrix();; matrix.postRotate(angle); System.out.println("angle2=" + angle); // 创建新的图片 Bitmap resizedBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true); return resizedBitmap; }
getimage代码
public static Bitmap getimage(String srcPath) { BitmapFactory.Options newOpts = new BitmapFactory.Options(); //开始读入图片,此时把options.inJustDecodeBounds 设回true了 newOpts.inJustDecodeBounds = true; Bitmap bitmap = BitmapFactory.decodeFile(srcPath,newOpts);//此时返回bm为空 newOpts.inJustDecodeBounds = false; int w = newOpts.outWidth; int h = newOpts.outHeight; //现在主流手机比较多是800*480分辨率,所以高和宽我们设置为 float hh = 800f;//这里设置高度为800f float ww = 480f;//这里设置宽度为480f //缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可 int be = 1;//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;//设置缩放比例 //重新读入图片,注意此时已经把options.inJustDecodeBounds 设回false了 bitmap = BitmapFactory.decodeFile(srcPath, newOpts); return compressImage(bitmap);//压缩好比例大小后再进行质量压缩 }
compressImage代码
public static Bitmap compressImage(Bitmap image) { ByteArrayOutputStream baos = new ByteArrayOutputStream(); image.compress(Bitmap.CompressFormat.JPEG, 100, baos);//质量压缩方法,这里100表示不压缩,把压缩后的数据存放到baos中 int options = 100; while ( baos.toByteArray().length / 1024>100) { //循环判断如果压缩后图片是否大于100kb,大于继续压缩 baos.reset();//重置baos即清空baos image.compress(Bitmap.CompressFormat.JPEG, options, baos);//这里压缩options%,把压缩后的数据存放到baos中 options -= 10;//每次都减少10 } ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());//把压缩后的数据baos存放到ByteArrayInputStream中 Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, null);//把ByteArrayInputStream数据生成图片 return bitmap; }