【问题标题】:How to rotate an image from input stream without loading it into memory?如何从输入流中旋转图像而不将其加载到内存中?
【发布时间】:2015-02-27 14:39:24
【问题描述】:

我浏览了这些主题,但仍然没有找到以下问题的答案。

Android rotate bitmap without making a copy

Android: rotate image without loading it to memory

Rotating images on android. Is there a better way?

JNI bitmap operations , for helping to avoid OOM when using large images


我有一个Uri,它代表一个大图像。我需要将此图像的旋转副本保存到 SD 卡。但是当我这样做时

BitmapFactory.decodeStream(contentResolver.openInputStream(uri));

我收到 OutOfMemoryError。

我想做的是这样的

    ContentResolver resolver = getContentResolver();
    InputStream inputStream = null;
    FileOutputStream outputStream = null;
    File imageFile = null;
    try {
        inputStream = resolver.openInputStream(uri);


        //I don't know how to apply this matrix to the bytes of InputStream
        Matrix matrix = new Matrix();
        matrix.postRotate(90);

        imageFile = createImageFile();

        outputStream = new FileOutputStream(imageFile);
        byte[] buffer = new byte[1024];
        while (inputStream.read(buffer) != -1) {

            //I'd like to apply the 'matrix' to 'buffer' here somehow but I can't
            //since 'buffer' contains the bytes of the image, not the pixel values of the bitmap
            outputStream.write(buffer);
        }
    } catch (IOException e) {
        throw new RuntimeException(e);
    } finally {
        Util.closeQuietly(inputStream);
        Util.closeQuietly(outputStream);
    }

如果有的话,有什么解决办法?

【问题讨论】:

  • 图像以编码方式(PNG、JPEG 等)保存在磁盘上。您必须解码图像才能旋转它。 JNI 不在 Java 堆上分配内存,因此应该避免 OOM。
  • @CommonsWare 谢谢,你可能是指这个库 github.com/AndroidDeveloperLB/AndroidJniBitmapOperations 这是我能想到的最好的东西,但它仍然需要在 Java 端构建 Bitmap,这意味着加载它进入记忆。不适用于 10Mb 以上的图像...
  • 存在 C/C++ 代码来读取图像文件并处理它们(例如,libmagick)。是否存在通往该代码的 Android JNI 桥接器,或者您是否必须编写一个,我不能说。

标签: android image image-processing bitmap rotation


【解决方案1】:

如果您可以接受较低质量的图像,您可以使用 BitmapFactory.Options 读取它 使用这些选项时,您通常无法直观地分辨出区别

 BitmapFactory.Options options = new BitmapFactory.Options();
 options.inSampleSize = 2; //Scale it down
 options.inPreferredConfig = Bitmap.Config.RBG_565; // Less memory intensive color format
 Bitmap bitmap = BitmapFactory.decodeStream( fis, null, options );

希望这会有所帮助。

如果不先阅读它,我不明白如何操作它。

【讨论】:

  • 不幸的是,我需要保存图像而不会丢失质量。
  • 如果您在应用程序中使用它,您不能只“按原样”存储未旋转的图像,然后在显示时使用矩阵旋转吗?
  • 我需要将图像发布到外部服务。所以我需要某种方式来按块而不是一次读取和处理图像(不幸的是,Bitmap android API 鼓励这样做)
猜你喜欢
  • 2023-03-10
  • 1970-01-01
  • 2017-09-22
  • 2022-01-01
  • 2013-11-22
  • 1970-01-01
  • 2013-03-25
  • 1970-01-01
  • 2013-04-24
相关资源
最近更新 更多