【问题标题】:How to rotate an image and save it without re compressing it?如何旋转图像并保存而不重新压缩它?
【发布时间】:2017-09-28 17:39:59
【问题描述】:

我有一个图像文件 (jpg),我需要旋转它。但是,我想避免在将其保存回磁盘时重新压缩它。他们有什么办法吗?

我这样保存图片:

  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();

【问题讨论】:

  • 你有什么尝试
  • 你如何保存这个放一些代码,以便我们更好地帮助你
  • 是的,我想旋转图像并避免重新压缩它...
  • 您确定不能只在图像的 EXIF 数据中设置旋转吗?这似乎会在根本不更改数据的情况下旋转它,但它是否适合您取决于您​​旋转图像的原因以及随后将显示它的内容。
  • (请注意,这个问题并不像某些人认为的那样奇怪:​​ 可以通过算法旋转 JPEG 而不会有损re压缩:stackoverflow.com/a/543729/300836,我猜这就是我们正在谈论的内容。)

标签: android jpeg android-bitmap image-compression


【解决方案1】:

也许您可以尝试将位图中的数据提取到字节数组并保存该数组。 (代码未经测试,可能不起作用)。

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();

【讨论】:

    【解决方案2】:

    使用 PNG 而不是 JPG。 PNG格式是带压缩的无损数据格式。 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();
    


    或者,您可以使用 Compressor 库,使用 WEBP 格式。
    WEBP 支持无损和有损。 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);
    

    【讨论】:

    • 不,png 将原始文件的大小增加 3 + 保存文件大约需要 7 秒 :( WebP 是一个不错的选择,但为什么质量为 75 而不是 80?90? 95 ?
    • @noa WEBP 的质量,它是 100。我只是从 github 站点复制并粘贴示例,我只是更正了它。
    • @noa 另外,使用WEBP需要API 14以上。 stackoverflow.com/questions/19308831/…
    • @noa 为什么需要旋转图像?如果您需要从相机旋转图像,您可以“setDisplayOrientation(90)”,无需自己旋转。 stackoverflow.com/questions/5309029/android-camera-rotate
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-30
    • 2012-09-28
    • 2019-12-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多