Bitmap compressed with quality = 100 larger file size than original

I am trying to send an image to a server. Before sending, I reduce its size and quality, and then fix any problem with rotation. My problem is that after the image is rotated, when I save it, the file is larger than before. Before the rotation size was 10092, and after rotation - 54226

// 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; } 
+7
source share
1 answer

You compress it with various quality measures. After rotation, you use quality 100, so it will be a larger file than the previous one, with quality 55.

When you compress an image, it doesn't matter what the current file size / quality is. This does not have a real impact on the result. Quality compression of 55 and then quality of 100 does not result in the file being the same size as simple compression of quality 55. This results in a file with a compression size of 100, because this is the last thing to deal with it.


For your specific code, I'm not sure I see that the reason is because it compresses it twice. Compression (file size) is not what caused OOM problems during rotation, but image sizes were the most likely culprits. Reducing the image before rotation should fix this, there is no need to save a temporary file.

All you have to do is run reduceImage() and then execute it with fixRotation() . Correct your rotation method so that it accepts a Bitmap instead of a path, so you don't need to save the file between them. Finally, save / compress it with any quality you want.

If you need a temporary file for any reason, use PNG for the first compression. Thus, it is lossless, so when you recompress the final image, you will not use JPG (lose) twice at low quality.

+4
source

All Articles