2013-03-04 30 views
7

Tôi đang cố gắng gửi hình ảnh đến máy chủ. Trước khi gửi nó, tôi đang giảm kích thước và chất lượng của nó, và sau đó sửa chữa bất kỳ vấn đề xoay. Vấn đề của tôi là, sau khi xoay hình ảnh, khi tôi lưu nó, tập tin lớn hơn trước. Trước khi kích thước xoay là 10092 và sau khi xoay là 54226Bitmap được nén với chất lượng = 100 kích thước tệp lớn hơn bản gốc

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

Trả lời

4

Bạn đang nén nó với các biện pháp chất lượng khác nhau. Sau khi xoay, bạn đang sử dụng chất lượng 100, do đó, nó sẽ là một tệp lớn hơn tệp trước đó, với chất lượng là 55.

Khi bạn nén hình ảnh, không quan trọng kích thước/chất lượng tệp hiện tại là gì . Điều đó không có tác động thực sự đến kết quả. Nén ở chất lượng 55, theo sau là 100 chất lượng, không không dẫn đến tệp có kích thước giống như nén chất lượng 55 đơn giản. Nó kết quả trong một tập tin với kích thước của 100 nén chất lượng, bởi vì đó là điều cuối cùng được thực hiện cho nó.


Đối với mã cụ thể của bạn, tôi không chắc chắn tôi thấy lý do đằng sau việc nén nó hai lần. Nén (kích thước tập tin) không phải là những gì đã gây ra vấn đề OOM của bạn khi quay, kích thước hình ảnh có nhiều khả năng là thủ phạm. Thu hẹp hình ảnh trước khi quay nên khắc phục điều đó, không cần phải lưu tệp tạm thời.

Tất cả những gì bạn cần làm là chạy reduceImage(), sau đó theo dõi nó với fixRotation(). Sửa phương thức xoay của bạn sao cho nó chấp nhận Bitmap thay vì đường dẫn, vì vậy bạn không cần lưu tệp ở giữa. Cuối cùng, lưu/nén nó ở bất cứ chất lượng nào bạn mong muốn.

Nếu bạn do cần tệp tạm thời vì một số lý do, hãy sử dụng PNG cho lần nén đầu tiên. Bằng cách này nó không mất mát, vì vậy khi bạn recompress hình ảnh cuối cùng, bạn sẽ không sử dụng JPG (lossy) hai lần với chất lượng thấp.

+0

Cảm ơn Geobits, nhưng tôi đang sử dụng chất lượng 100 với tệp được tạo trước đó (chất lượng 55), không phải với tệp gốc. Hoặc đó là những gì tôi nghĩ rằng tôi đang làm. Sau khi lưu hình ảnh với chất lượng 55, kích thước tệp là 10092. Sau đó, tôi lấy tệp đó, xoay tệp và lưu tệp với chất lượng 100 và kích thước tệp bây giờ là 54226 –

+0

Cảm ơn Geobits, tôi nghĩ rằng tôi hiểu nó now.Is có cách nào để tôi có thể sửa chữa các vấn đề xoay, giảm kích thước và chất lượng của nó, mà không có một tập tin cuối cùng lớn hơn bản gốc? Tôi đã thử quay đầu tiên và sau đó giảm kích thước và chất lượng, nhưng nó đã cho tôi OutOfMemoryException khi quay. Ý tưởng nào? –

+0

Đã thêm vào câu trả lời – Geobits

Các vấn đề liên quan