博客源址:bitmap处理BitmapFactory.Options.inSampleSize
博客时间:2013-12-12 11:49
<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">今天也是项目需要上传拍照,现在手机拍一张多有一两M了,我们限制的是100k就开始了图片缩小处理,</span>
我的方案是先压缩分辨率,再压缩质量。我的300w像素照片也有2048*1536了,上传的照片分辨率没必要那么大切涨内存
借鉴网上方法
public static byte[] comp(String zpath) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
BitmapFactory.Options newOpts = new BitmapFactory.Options();
newOpts.inJustDecodeBounds = true;
Bitmap bitmap = BitmapFactory.decodeFile(path, newOpts);//打开空图片获取分辨率
baos.reset();
newOpts.inSampleSize = getinSampleSize(newOpts);
newOpts.inJustDecodeBounds = false;
Bitmap bitmap1 = BitmapFactory.decodeFile(path, newOpts);
boolean b = bitmap1.compress(CompressFormat.PNG, 100, baos);
System.out.println("lenght:"+(baos.toByteArray().length/1024));
return baos.toByteArray();//
}
public static int getinSampleSize(BitmapFactory.Options options) {
final int height = options.outHeight;
final int width = options.outWidth;
float reqHeight=800.0f;
float reqWidth=480.0f;
int inSampleSize = 1;
if (height > width && height>reqHeight) {
inSampleSize = (int) Math.ceil(height/ reqHeight);
System.out.println(inSampleSize+"inSampleSize");
}
else if(height<=width && width>reqWidth){
inSampleSize = (int) Math.ceil( width / reqWidth);
System.out.println(inSampleSize+"inSampleSize");
}
System.out.println("inSampleSize" + inSampleSize);
return inSampleSize;
}
但是问题也出来了,
1,当newOpts.inSampleSize=3的时候,图片其实压缩了2倍,而google只说建议用2 的整数倍(只按照2的整数次幂倍缩小)。没说不能用单数,待确定;
2,当拍照之后我BitmapFactory.decodeFile(path)取出图片再转成流存入,发现原本800k的照片居然有3m了,大概看到网上说的
3m的照片转成bitmap之后居然有30m,还说bitmap是用图片的分辨率高*宽在乘以颜色编码,那就说和照片本地大小没关系咯,我测试还是右关系的
不知道原因i。有时间在深究下,留下问好,让路人解答
2014年10月20日 17:00:59 为自己整理了一下 目的就是为了处理上传图片 因为100k还是比较大需要后台上传 于是乎就这样了
/**
* 分辨率压缩 在质量压缩
*
* @param 路劲
* @return </br> 处理之后的路劲
* @throws IOException
*/
public static String perUploadPic(String path) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
BitmapFactory.Options newOpts = new BitmapFactory.Options();
newOpts.inJustDecodeBounds = true;
BitmapFactory.decodeFile(path, newOpts);// 打开空图片获取分辨率
newOpts.inSampleSize = getinSampleSize(newOpts);// 设置缩放倍数
newOpts.inJustDecodeBounds = false;
try {
Bitmap bitmap1 = BitmapFactory.decodeFile(path, newOpts);
bitmap1.compress(CompressFormat.JPEG, 80, baos);
} catch (OutOfMemoryError e) {
Log.e("OutOfMemoryError", "图片上传压缩初次分辨率失败");
newOpts.inSampleSize = newOpts.inSampleSize + 2;
Bitmap bitmap1 = BitmapFactory.decodeFile(path, newOpts);
bitmap1.compress(CompressFormat.JPEG, 80, baos);
}
Log.e("压缩后分辨率:", newOpts.outWidth + "*" + newOpts.outHeight);
Log.e("分辨率压缩后的大小:", (baos.toByteArray().length / 1024) + "");
// ByteArrayOutputStream baos = new ByteArrayOutputStream();
// baos.write(bytes);
Bitmap bitmap = null;
int options = 90;
while (baos.toByteArray().length / 1024 > 100) { //
if (bitmap == null)
bitmap = BitmapFactory.decodeByteArray(baos.toByteArray(), 0,
baos.toByteArray().length);
else
baos.reset();
bitmap.compress(Bitmap.CompressFormat.JPEG, options, baos);//
options -= 5;//
Log.e("baos.toByteArray().length:", +baos.toByteArray().length + "");
}
Log.e("质量压缩后的大小:", (baos.toByteArray().length / 1024) + "");
FileOutputStream out = null;
File file = null;
try {
String[] name = path.split("/");//路劲大家自己写哈
file = new File(getSDPath() + "/" + Constant.path.PAHN + "/"
+ Constant.path.cameraper + "/" + name[name.length - 1]);
if (!file.getParentFile().exists())
file.getParentFile().mkdirs();
if (!file.exists())
file.createNewFile();
out = new FileOutputStream(file);
out.write(baos.toByteArray());
out.flush();
out.close();
} catch (IOException e) {
// TODO Auto-generated catch block
try {
out.close();
baos.reset();
baos = null;
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
Log.e("yung", "待上传图片压缩处理失败:" + path);
e.printStackTrace();
}
return file.getAbsolutePath();
}
/**
* 获取图片压缩的比率
*
* @param options
* @return
*/
public static int getinSampleSize(BitmapFactory.Options options) {
final int height = options.outHeight;
final int width = options.outWidth;
float reqHeight = 960.0f;//根据自己需要确定分辨率长或者宽最大不超过960 并且按照原来比例
float reqWidth = 960.0f;
int inSampleSize = 1;
if (height > width && height > reqHeight) {
inSampleSize = (int) Math.ceil(height / reqHeight);
} else if (height <= width && width > reqWidth) {
inSampleSize = (int) Math.ceil(width / reqWidth);
}
System.out.println("压缩前分辨率:" + width + "*" + height + " 压缩倍数:"
+ inSampleSize);
return inSampleSize;
}
public static File getSDPath() {
File sdDir = null;
if (sdCardAvailable()) {
sdDir = Environment.getExternalStorageDirectory();// 获取跟目录
}
return sdDir;
}