2013-03-04 87 views
7

我正尝试将图像发送到服务器。在发送之前,我正在缩小它的尺寸和质量,然后解决任何旋转问题。我的问题是,旋转图像后,当我保存它时,文件比以前更大。在旋转大小为10092之前和旋转之后是54226压缩质量比原始文件大100的位图

// 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; 
} 

回答

4

您正在使用不同的质量度量进行压缩。旋转后,您使用的质量100,所以它将是一个比前一个更大的文件,质量为55.

压缩图像时,无关紧要当前文件大小/质量。这对结果没有实际影响。以55质量压缩,然后是100质量,而不是导致与简单55质量压缩具有相同大小的文件。它会生成一个大小为100的压缩文件,因为这是对它做的最后一件事。


对于你的具体代码,我不知道我看到背后压缩它的原因。压缩(文件大小)不是在旋转时导致OOM问题的原因,图像尺寸最有可能是罪魁祸首。在旋转之前缩小图像应该可以解决这个问题,不需要保存临时文件。

您只需运行reduceImage(),然后按照fixRotation()进行跟踪。修正你的旋转方法,以便它接受Bitmap而不是路径,所以你不需要在两者之间保存文件。最后,以您想要的任何质量保存/压缩它。

如果你由于某种原因需要临时文件,请使用PNG进行第一次压缩。这样它就没有损失,所以当你重新压缩最终图像时,你将不会以低质量两次使用JPG(有损)。

+0

感谢Geobits,但我使用质量100与前生成的文件(质量55),而不是原来的。或者那是我认为我正在做的事。 以质量55保存图像后,文件大小为10092.然后,我拿起该文件,旋转它,并保存质量100,文件大小现在是54226 – 2013-03-05 10:10:12

+0

感谢Geobits,我想我是理解它现在。是否有任何方法可以解决旋转问题,减小尺寸和质量,而不会有比原始文件更大的最终文件? 我尝试做第一次旋转,然后减小大小和质量,但它旋转时给了我OutOfMemoryException。有任何想法吗? – 2013-03-06 11:11:28

+0

已添加到答复 – Geobits 2013-03-06 12:58:02

相关问题