【问题标题】:Modify image from file and save从文件修改图像并保存
【发布时间】:2013-11-01 17:55:00
【问题描述】:

我需要从文件加载图像到 ImageView 上画一些东西并保存到同一个文件。我的所有修改都绘制在名为mCanvasView 的单独视图中。这是我的保存代码:

    private void saveResult() {
    OutputStream stream = null;
    try {
        Bitmap result;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
            BitmapFactory.Options options = new BitmapFactory.Options();
            options.inMutable = true;
            result = BitmapFactory.decodeFile(mFilePath, options);
        } else {
            Bitmap bitmap = BitmapFactory.decodeFile(mFilePath);
            result = bitmap.copy(Bitmap.Config.ARGB_8888, true);
            bitmap.recycle();
        }
        float resultWidth = result.getWidth();
        float resultHeight = result.getHeight();
        Canvas canvas = new Canvas(result);
        Bitmap overlay = mCanvasView.getDrawingCache();
        Matrix matrix = new Matrix();
        matrix.setScale(resultWidth / overlay.getWidth(), resultHeight
                / overlay.getHeight());
        canvas.drawBitmap(overlay, matrix, new Paint());
        stream = new FileOutputStream(mFilePath);
        result.compress(CompressFormat.PNG, 100, stream);
    } catch (Exception e) {
        e.printStackTrace();
        leaveActivityWithMissingData();
    } finally {
        IOUtils.closeQuietly(stream);
    }
}

首先 - 它真的很慢。我不明白为什么。其次,如果图像以纵向模式拍摄,则保存的图像将被旋转。为什么?我不应用任何轮换。

我已经像这样修改了我的代码以使用来自 EXIF 的旋转数据:

    OutputStream stream = null;
    try {
        Bitmap original;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
            BitmapFactory.Options options = new BitmapFactory.Options();
            options.inMutable = true;
            original = BitmapFactory.decodeFile(mFilePath, options);
        } else {
            Bitmap bitmap = BitmapFactory.decodeFile(mFilePath);
            original = bitmap.copy(Bitmap.Config.ARGB_8888, true);
            bitmap.recycle();
        }
        int resultWidth = original.getWidth();
        int resultHeight = original.getHeight();
        int rotation = Utils.getRotation(mFilePath);
        if (rotation % 180 != 0) {
            resultHeight = original.getWidth();
            resultWidth = original.getHeight();
        }
        Bitmap result = Bitmap.createBitmap(resultWidth, resultHeight,
                Config.ARGB_8888);
        Canvas canvas = new Canvas(result);
        Matrix rotationMatrix = new Matrix();
        rotationMatrix.setRotate(rotation, resultWidth / 2,
                resultHeight / 2);
        canvas.drawBitmap(original, rotationMatrix, new Paint());
        original.recycle();
        Bitmap overlay = mCanvasView.getDrawingCache();
        Matrix scaleMatrix = new Matrix();
        scaleMatrix.setScale(resultWidth / overlay.getWidth(), resultHeight
                / overlay.getHeight());
        canvas.drawBitmap(overlay, scaleMatrix, new Paint());
        overlay.recycle();

        stream = new FileOutputStream(mFilePath);
        result.compress(CompressFormat.PNG, 100, stream);
        result.recycle();
    } catch (Exception e) {
        e.printStackTrace();
        leaveActivityWithMissingData();
    } finally {
        IOUtils.closeQuietly(stream);
    }

但这会导致每次调用都出现 OOM。我究竟做错了什么?

【问题讨论】:

标签: android image-processing bitmap


【解决方案1】:

检查this 可能有助于了解性能问题。
另外,完成压缩后不要忘记关闭您的stream

至于旋转 - 您的相机是否将原始预览模式设置为 setDisplayOrientation(90) 或类似?然后你总是可以通过应用matrix.postRotate(90);来旋转以匹配图像以进行预览

【讨论】:

  • 我通过 Intent 使用默认相机。
  • @Lingviston @Lingviston 这个stackoverflow.com/questions/14066038 解释了如何获取有关发生旋转的信息,使用此信息您可以适当地旋转图像
  • 看起来所有这些转换都是相当消耗内存的操作。我无法理解他们使如此简单的操作变得如此困难。没有办法将我的叠加层直接“绘制”到带有初始图像的文件中?
  • 首先,您确定带有初始图像的文件包含正确定向的图像吗?其次,我建议捕获位图,根据上面的链接在需要时旋转它,应用您的叠加层,然后将其保存到文件中
  • 捕获和编辑是独立的操作。它们是通过应用程序的不同部分完成的。
猜你喜欢
  • 2022-11-03
  • 1970-01-01
  • 1970-01-01
  • 2021-05-31
  • 2017-04-27
  • 1970-01-01
  • 2016-11-12
  • 2014-06-09
  • 2019-05-07
相关资源
最近更新 更多