1

I have an Image File (jpg) and i need to rotate it. However, i would like to avoid to re compress it when saving it back to the disk. Is their any way to do this?

I save the image like this:

  matrix.setRotate(-90);
  Bitmap bitmap = BitmapFactory.decodeFile(imagePath, options);
  Bitmap bmRotated = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
  bitmap.recycle();

  FileOutputStream fileoutputstream = new FileOutputStream(imagePath);
  bmRotated.compress(CompressFormat.JPEG, 100, fileoutputstream);
  fileoutputstream.flush();
   fileoutputstream.close();
  bmRotated.recycle();
Igor Fridman
  • 1,267
  • 1
  • 16
  • 30
noa
  • 59
  • 8
  • Did you try anything – UltimateDevil Sep 28 '17 at 07:40
  • How are you saving this put some code so we can help you better – UltimateDevil Sep 28 '17 at 07:42
  • @VikasTiwari: done, i updated the question – noa Sep 28 '17 at 07:57
  • Non-compressing JPEG files are _very_ seldom encountered, I doubt, that your source file belongs to that category, so also the rotated version will be compressed. – guidot Sep 28 '17 at 07:58
  • What do you mean you don't want to compress? JPEG is a compressed format. Or are you trying to preserve image quality after compression? If so, use PNG format. – Nabin Bhandari Sep 28 '17 at 08:04
  • 1
    yes, i want to rotate the image and avoid re compressing it ... – noa Sep 28 '17 at 08:06
  • 1
    Are you sure you can't just set the rotation in the image's EXIF data? That will appear to rotate it without changing the data at all, but whether it would work for you depends on the reason you're rotating the image and what's then going to display it. – Matt Gibson Sep 28 '17 at 08:12
  • If you don;t want to work with exif and you want to store imaga as jpeg -there is no way without recompress. JPEG is format with compression. Any time your open it as bitmap in android - it decompresing to byte array. When you trying to save it as JPEG - you use compression of jpeg encoder – Beyka Sep 28 '17 at 08:17
  • 2
    (Note that this isn't as odd a question as some people seem to think: it *is* possible to algorithmically rotate a JPEG without lossy *re*compression: https://stackoverflow.com/a/543729/300836, which I'm guessing is what we're talking about.) – Matt Gibson Sep 28 '17 at 08:18

2 Answers2

0

Maybe you can try to extract the data from your bitmap to a byte array and save that array. (Code not tested, maybe it does not work).

Bitmap bitmap = new Bitmap()...
int width = bitmap.getWidth();
int height = bitmap.getHeight();

int size = bitmap.getRowBytes() * bitmap.getHeight();
ByteBuffer byteBuffer = ByteBuffer.allocate(size);
bitmap.copyPixelsToBuffer(byteBuffer);
byte[] byteArray = byteBuffer.array();

FileOutputStream output = new FileOutputStream("filename");
output.write(byteArray);
output.close();
Miguel Isla
  • 1,379
  • 14
  • 25
0

Use PNG instead of JPG. PNG format is loseless data format with compress. https://en.wikipedia.org/wiki/Portable_Network_Graphics

matrix.setRotate(-90);
Bitmap bitmap = BitmapFactory.decodeFile(imagePath, options);
Bitmap bmRotated = Bitmap.createBitmap(bitmap, 0, 0, 
bitmap.getWidth(), bitmap.getHeight(), matrix, true);
bitmap.recycle();

FileOutputStream fileoutputstream = new FileOutputStream(imagePath);
bmRotated.compress(CompressFormat.PNG, 100, fileoutputstream);
fileoutputstream.flush();
fileoutputstream.close();
bmRotated.recycle();


Or, you can use Compressor library, to use WEBP format.
WEBP supports both lossless and loss. https://en.wikipedia.org/wiki/WebP

https://github.com/zetbaitsu/Compressor

compressedImage = new Compressor(this)
        .setMaxWidth(640)
        .setMaxHeight(480)
        .setQuality(100)
        .setCompressFormat(Bitmap.CompressFormat.WEBP)
        .setDestinationDirectoryPath(Environment.getExternalStoragePublicDirectory(
          Environment.DIRECTORY_PICTURES).getAbsolutePath())
        .compressToFile(actualImage);
Stanley Ko
  • 3,383
  • 3
  • 34
  • 60
  • no, png will increase by 3 the size of the original file + it's take around 7 seconds to save the file :( WebP is a good alternative, but why 75 as quality and not 80? 90? 95 ? – noa Sep 28 '17 at 09:21
  • @noa quality of WEBP, it is 100. I just copy and paste example from the github site, and I just corrected it. – Stanley Ko Sep 28 '17 at 09:46
  • @noa In addition, you need API 14 or above to use WEBP. https://stackoverflow.com/questions/19308831/android-java-lang-nosuchfielderror-android-graphics-bitmapcompressformat-web – Stanley Ko Sep 28 '17 at 09:47
  • @noa Why do you need to rotate image? If you need to rotate image from camera, you can "setDisplayOrientation(90)" and no need to rotate by yourself. https://stackoverflow.com/questions/5309029/android-camera-rotate – Stanley Ko Sep 28 '17 at 09:52