Android 位图压缩质量=比原始文件大100
我正在尝试向服务器发送图像。在发送之前,我正在减小它的大小和质量,然后修复任何旋转问题。我的问题是,在旋转图像后,当我保存它时,文件比以前大。旋转前尺寸为10092,旋转后尺寸为54226Android 位图压缩质量=比原始文件大100,android,bitmap,compression,Android,Bitmap,Compression,我正在尝试向服务器发送图像。在发送之前,我正在减小它的大小和质量,然后修复任何旋转问题。我的问题是,在旋转图像后,当我保存它时,文件比以前大。旋转前尺寸为10092,旋转后尺寸为54226 // Scale image to reduce it Bitmap reducedImage = reduceImage(tempPhotoPath); // Decrease photo quality FileOutputStream fos = new FileOutputStream(tempPh
// Scale image to reduce it
Bitmap reducedImage = reduceImage(tempPhotoPath);
// Decrease photo quality
FileOutputStream fos = new FileOutputStream(tempPhotoFile);
reducedImage.compress(CompressFormat.JPEG, 55, fos);
fos.flush();
fos.close();
// Check and fix rotation issues
Bitmap fixed = fixRotation(tempPhotoPath);
if(fixed!=null)
{
FileOutputStream fos2 = new FileOutputStream(tempPhotoFile);
fixed.compress(CompressFormat.JPEG, 100, fos2);
fos2.flush();
fos2.close();
}
public Bitmap reduceImage(String originalPath)
{
// Decode image size
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
o.inPurgeable = true;
o.inInputShareable = true;
BitmapFactory.decodeFile(originalPath, o);
// The new size we want to scale to
final int REQUIRED_SIZE = 320;
// Find the correct scale value. It should be the power of 2.
int width_tmp = o.outWidth, height_tmp = o.outHeight;
int scale = 1;
while (true) {
if (width_tmp / 2 < REQUIRED_SIZE || height_tmp / 2 < REQUIRED_SIZE) {
break;
}
width_tmp /= 2;
height_tmp /= 2;
scale *= 2;
}
// Decode with inSampleSize
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inPurgeable = true;
o2.inInputShareable = true;
o2.inSampleSize = scale;
Bitmap bitmapScaled = null;
bitmapScaled = BitmapFactory.decodeFile(originalPath, o2);
return bitmapScaled;
}
public Bitmap fixRotation(String path)
{
Bitmap b = null;
try
{
//Find if the picture is rotated
ExifInterface exif = new ExifInterface(path);
int degrees = 0;
if(exif.getAttribute(ExifInterface.TAG_ORIENTATION).equalsIgnoreCase("6"))
degrees = 90;
else if(exif.getAttribute(ExifInterface.TAG_ORIENTATION).equalsIgnoreCase("8"))
degrees = 270;
else if(exif.getAttribute(ExifInterface.TAG_ORIENTATION).equalsIgnoreCase("3"))
degrees = 180;
if(degrees > 0)
{
BitmapFactory.Options o = new BitmapFactory.Options();
o.inPurgeable = true;
o.inInputShareable = true;
Bitmap bitmap = BitmapFactory.decodeFile(path, o);
int w = bitmap.getWidth();
int h = bitmap.getHeight();
Matrix mtx = new Matrix();
mtx.postRotate(degrees);
b = Bitmap.createBitmap(bitmap, 0, 0, w, h, mtx, true);
}
}
catch(Exception e){e.printStackTrace();}
return b;
}
//缩放图像以缩小它
位图还原图像=还原图像(tempPhotoPath);
//降低照片质量
FileOutputStream fos=新的FileOutputStream(tempPhotoFile);
压缩(CompressFormat.JPEG,55,fos);
fos.flush();
fos.close();
//检查并修复旋转问题
位图固定=固定旋转(tempPhotoPath);
如果(已修复!=null)
{
FileOutputStream fos2=新的FileOutputStream(tempPhotoFile);
固定。压缩(CompressFormat.JPEG,100,fos2);
fos2.flush();
fos2.close();
}
公共位图还原图像(字符串原始路径)
{
//解码图像大小
BitmapFactory.Options o=新的BitmapFactory.Options();
o、 inJustDecodeBounds=true;
o、 inpurgable=true;
o、 inInputShareable=true;
解码文件(originalPath,o);
//我们要扩展到的新尺寸
所需的最终int_尺寸=320;
//找到正确的刻度值。它应该是2的幂。
内部宽度=o.向外宽度,高度=o.向外高度;
int标度=1;
while(true){
如果(宽度\u tmp/2<所需尺寸| |高度\u tmp/2<所需尺寸){
打破
}
宽度_tmp/=2;
高度_tmp/=2;
比例*=2;
}
//用inSampleSize解码
BitmapFactory.Options o2=新的BitmapFactory.Options();
o2.InPurgable=真;
o2.inInputShareable=真;
o2.inSampleSize=刻度;
位图bitmapScaled=null;
bitmapScaled=BitmapFactory.decodeFile(原始路径,o2);
返回位图缩放;
}
公共位图固定旋转(字符串路径)
{
位图b=null;
尝试
{
//查找图片是否已旋转
ExifInterface exif=新的ExifInterface(路径);
整数度=0;
if(exif.getAttribute(ExifInterface.TAG_ORIENTATION.equalsIgnoreCase(“6”))
度=90度;
else if(exif.getAttribute(ExifInterface.TAG_ORIENTATION.equalsIgnoreCase(“8”))
度=270度;
else if(exif.getAttribute(ExifInterface.TAG_ORIENTATION.equalsIgnoreCase(“3”))
度=180度;
如果(度>0)
{
BitmapFactory.Options o=新的BitmapFactory.Options();
o、 inpurgable=true;
o、 inInputShareable=true;
位图位图=位图工厂.decodeFile(路径,o);
int w=bitmap.getWidth();
int h=bitmap.getHeight();
矩阵mtx=新矩阵();
mtx.后旋转(度);
b=Bitmap.createBitmap(位图,0,0,w,h,mtx,true);
}
}
catch(异常e){e.printStackTrace();}
返回b;
}
您正在使用不同的质量度量对其进行压缩。旋转后,您使用的是质量100,因此它将比上一个文件大,质量55
压缩图像时,当前文件大小/质量如何并不重要。这对结果没有实际影响。以55质量压缩,然后是100质量压缩,不会产生与简单的55质量压缩相同大小的文件。它会产生一个大小为100质量压缩的文件,因为这是对它做的最后一件事
对于您的特定代码,我不确定我是否看到了压缩它两次的原因。旋转时,压缩(文件大小)并不是导致OOM问题的原因,图像尺寸很可能是罪魁祸首。旋转前缩小图像应该可以解决这个问题,无需保存临时文件 您只需运行
reduceImage()
,然后使用fixRotation()
进行后续操作。修正旋转方法,使其接受位图
,而不是路径,这样就不需要在两者之间保存文件。最后,以您想要的任何质量保存/压缩它
如果出于某种原因确实需要临时文件,请在第一次压缩时使用PNG。这样,它是无损的,因此当您重新压缩最终图像时,您不会以低质量使用JPG(有损)两次。谢谢Geobits,但我将质量100用于之前生成的文件(质量55),而不是原始文件。或者这就是我认为我正在做的。保存质量为55的图像后,文件大小为10092。然后,我拿了那个文件,旋转它,并以100的质量保存它,现在的文件大小是54226位,我想我现在理解它了。有没有什么方法可以解决旋转问题,减小它的大小和质量,而不必最终的文件比原来的文件大?我试着先做旋转,然后缩小尺寸和质量,但旋转时会出现OutOfMemoryException。有什么想法吗?