三星手机拍照强制切换到横屏及照片旋转问题

最近在做项目,项目里面有拍照上传的功能,无非就是吊起系统拍照功能,然后获取所拍照的地址,然后上传即可。但是当我无意间拿了一部三星手机装了App之后,当使用拍照功能的时候,拍完之后,界面并没有出现所拍的照片,之后才知道是三星手机在拍照的时候会强制切换到横屏,导致生命周期重走了,所以拍出来的照片所保存的地址也跟着没有了,然后我在清单文件中配置了该Activity的android:configChanges="orientation|keyboardHidden",然而并没有什么卵用,幸好Activity提供了onSaveInstanceState方法,用于保存数据,重走onCreate的时候再拿出来即可解决以上的问题,代码如下:

@Override
	protected void onCreate(Bundle savedInstanceState) {
		
		super.onCreateBM(savedInstanceState);
		if(savedInstanceState != null){
			//因为三星部分机型,拍照的时候他会强制切换到横屏,导致该类重走生命周期,所有的数据重置了,所以要保存之前的数据,在此重新获取
			//三星的camera强制切换到横屏  导致Activity重启生命周期 (但是部分机型  配置  android:configChanges  也不能阻止横竖屏切换);
			//重新获取重走生命周期之前的数据
			mFiles = (List<File>) savedInstanceState.getSerializable("mFiles");
			mHomeWork =  (List<HomeWork>) savedInstanceState.getSerializable("mHomeWork");
			mVoiceWork = savedInstanceState.getStringArrayList("mVoiceWork");
			mPicWork = savedInstanceState.getStringArrayList("mPicWork");
			mHomeworkList = savedInstanceState.getStringArrayList("mHomeworkList");
			
			//设置数据到相应的控件上
		}
	}
	
	@Override
	protected void onSaveInstanceState(Bundle savedInstanceState) {
		//保存数据
		savedInstanceState.putStringArrayList("mHomeworkList", (ArrayList<String>) mHomeworkList);
		savedInstanceState.putStringArrayList("mPicWork", (ArrayList<String>) mPicWork);
		savedInstanceState.putStringArrayList("mVoiceWork", (ArrayList<String>) mVoiceWork);
		savedInstanceState.putSerializable("mFiles",(Serializable) mFiles);
		savedInstanceState.putSerializable("mHomeWork",(Serializable) mHomeWork);
		
	}
当解决了强制横屏的问题,三星手机又来了一个旋转照片的毛病,拍出来的照片居然被旋转了90°或180°,感觉整个人不好了。百度了一下,下面就来整理一下,有关图片旋转问题,还有图片压缩问题。
拍出来的照片,可以根据ExifInterface类来获取其旋转的角度。但是旋转的时候,是通过Bitmap来做的,所以就需要将本地图片在读取成Bitmap,但是过大的图片加载到内存肯定是要崩的,所以就需要对照片进行压缩,但是处理拍出来的照片的时候,切记一定要先获取其旋转的角度,再压缩,然后再旋转。如果先压缩,压缩后的照片就不是本来的那张原始照片的,并没有旋转,所以它获取出来的旋转角度是0°。以下是相关的代码

import java.io.File;
import java.io.IOException;

import android.graphics.Bitmap;
import android.graphics.Matrix;
import android.media.ExifInterface;
/**
 * 获取图片角度和旋转图片
 * @author chenj
 *
 */
public class CaremaUtil {
	
	/**
	 * 读取图片的旋转的角度
	 *
	 * @param path
	 *            图片绝对路径
	 * @return 图片的旋转角度
	 */
	public static int getBitmapDegree(File pathFile) {
		return getBitmapDegree(pathFile.getAbsolutePath());
	}

	/**
	 * 读取图片的旋转的角度
	 *
	 * @param path
	 *            图片绝对路径
	 * @return 图片的旋转角度
	 */
	public static 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();
		}
		return degree;
	}

	/**
	 * 将图片按照某个角度进行旋转
	 *
	 * @param bm
	 *            需要旋转的图片
	 * @param degree
	 *            旋转角度
	 * @return 旋转后的图片
	 */
	public static 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) {
		}
		if (returnBm == null) {
			returnBm = bm;
		}
		if (bm != returnBm) {
			bm.recycle();
		}
		return returnBm;
	}

}

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
/**
 * 读取和保存图片
 * @author chenj
 *
 */
public class BitmapUtil {
	/**
	 * 读取图片
	 * @param filePath
	 * @return
	 */
	public static Bitmap getBitmapFromPath(String filePath){
		Bitmap decodeFile = BitmapFactory.decodeFile(filePath);
		return decodeFile;
	}
	/**
	 * 读取图片
	 * @param file
	 * @return
	 */
	public static Bitmap getBitmapFromFile(File file){
		return getBitmapFromPath(file.getAbsolutePath());
	}
	
	/**
	 * 保存Bitmap到本地
	 * @param bitmap
	 * @param file
	 */
	public static void saveBitmapToSD(Bitmap bitmap, File file){
		try {
			boolean delete = file.delete();
			FileOutputStream fos = new FileOutputStream(file);
			bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);//这里100表示不压缩,将不压缩的数据存放到baos中
			//回收图片,清理内存
			if(bitmap != null && !bitmap.isRecycled()){
				bitmap.recycle();
				bitmap = null;
			    System.gc();
			}
			fos.flush();
			fos.close();
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}                
		
		
		
	}
}

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.UUID;

import com.bm.app.App;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.BitmapFactory.Options;
import android.text.TextUtils;
/**
 * 压缩图片
 * @author chenj
 *
 */
public class CompressUtil {
	//保存的路径
	private static String mSavePath = new File(App.getInstance().getExternalCacheDir(),"aaa/bbb/ccc").getAbsolutePath();
	/**
	 * 压缩文件,源文件和压缩后的文件都存在,源文件并没有被删除
	 * @param pathFile
	 * @return
	 */
	public static File compress(File pathFile){
		//如果小于500KB就直接返回,不进行压缩
		if(pathFile.length() < 1024 * 500){
			 return pathFile;
		}
		
		File file = new File(mSavePath);
		if(!file.exists()){
			file.mkdirs();
		}
		String imageFileName = UUID.randomUUID().toString()+getFileSuffix(pathFile.getAbsolutePath());
		//定义一个file,为压缩后的图片
		File f = new File(mSavePath,imageFileName);
		try{
		//先将所选图片转化为流的形式,path所得到的图片路径
		 FileInputStream is = new  FileInputStream(pathFile);
		 int size = 3;
		 if(pathFile.length() < 1024 * 500){
			 size = 1;
		 }else if(pathFile.length() > 1024 * 1024 * 5){
			 size = 5;
		 }
		 
		 Options options = new Options();
		 options.inSampleSize = size;
		 //将图片缩小为原来的  1/size ,不然图片很大时会报内存溢出错误
		 Bitmap image = BitmapFactory.decodeStream(is,null,options);
		
		 is.close();
		
		ByteArrayOutputStream baos = new ByteArrayOutputStream();                
		image.compress(Bitmap.CompressFormat.JPEG, 100, baos);//这里100表示不压缩,将不压缩的数据存放到baos中
		int per = 100;                
		while (baos.toByteArray().length / 1024 > 500) { // 循环判断如果压缩后图片是否大于500kb,大于继续压缩
		baos.reset();// 重置baos即清空baos
		image.compress(Bitmap.CompressFormat.JPEG, per, baos);// 将图片压缩为原来的(100-per)%,把压缩后的数据存放到baos中
		per -= 10;// 每次都减少10
		               
		}
		//回收图片,清理内存
		if(image != null && !image.isRecycled()){
		    image.recycle();
		    image = null;
		    System.gc();
		}
		ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());// 把压缩后的数据baos存放到ByteArrayInputStream中
		baos.close();
		FileOutputStream os;
		os = new FileOutputStream(f);
		//将输入流复制到输出流中
		copyStream(isBm, os);
		isBm.close();
		os.close();
		}catch(Exception e){
			e.printStackTrace();
		}
		return f;
	}
	
	/**
	 * 压缩源文件,只保存压缩后的文件,源文件将被删除,压缩后的文件名和源文件一样
	 * @param pathFile
	 * @return
	 */
	public static File compressSourceFile(String path){
		return compressSourceFile(new File(path));
	}
	
	/**
	 * 压缩源文件,只保存压缩后的文件,源文件将被删除,压缩后的文件名和源文件一样
	 * @param pathFile
	 * @return
	 */
	public static File compressSourceFile(File pathFile){
		
		try{
		//先将所选图片转化为流的形式,path所得到的图片路径
		 FileInputStream is = new  FileInputStream(pathFile);
		 int size = 3;
		 if(pathFile.length() < 1024 * 500){
			 size = 1;
		 }else if(pathFile.length() > 1024 * 1024 * 5){
			 size = 5;
		 }
		 
		 Options options = new Options();
		 options.inSampleSize = size;
		 //将图片缩小为原来的  1/size ,不然图片很大时会报内存溢出错误
		 Bitmap image = BitmapFactory.decodeStream(is,null,options);
		
		 is.close();
		
		ByteArrayOutputStream baos = new ByteArrayOutputStream();                
		image.compress(Bitmap.CompressFormat.JPEG, 100, baos);//这里100表示不压缩,将不压缩的数据存放到baos中
		int per = 100;                
		while (baos.toByteArray().length / 1024 > 500) { // 循环判断如果压缩后图片是否大于500kb,大于继续压缩
		baos.reset();// 重置baos即清空baos
		image.compress(Bitmap.CompressFormat.JPEG, per, baos);// 将图片压缩为原来的(100-per)%,把压缩后的数据存放到baos中
		per -= 10;// 每次都减少10
		               
		}
		//回收图片,清理内存
		if(image != null && !image.isRecycled()){
		    image.recycle();
		    image = null;
		    System.gc();
		}
		pathFile.delete();//删除源文件
		ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());// 把压缩后的数据baos存放到ByteArrayInputStream中
		baos.close();
		FileOutputStream os;
		os = new FileOutputStream(pathFile);
		//将输入流复制到输出流中
		copyStream(isBm, os);
		isBm.close();
		os.close();
		}catch(Exception e){
			e.printStackTrace();
		}
		return pathFile;
	}
	
	
	/**
	 * 获取文件的后缀名
	 * @param path
	 * @return
	 */
	public static String getFileSuffix(String path){
		if(path == null) return ".png";
		int lastIndexOf = path.lastIndexOf(".");
		if(lastIndexOf == -1) return ".png";
		return path.substring(lastIndexOf);
	}
	/**
	 * 流复制
	 * @param is
	 * @param os
	 */
	public static void copyStream(InputStream is,OutputStream os){
		try{
			int index = -1;
			byte[] bys = new byte[1024 * 8];
			while((index = is.read(bys)) != -1){
				os.write(bys, 0, index);
			}
		}catch(Exception e){
			e.printStackTrace();
		}
		
	}
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值