【问题标题】:Rotate a bitmap using render script android使用渲染脚本android旋转位图
【发布时间】:2015-12-10 02:33:50
【问题描述】:

当我使用以下代码时,最终会出现内存不足异常。经过研究,渲染脚本看起来像是一个不错的候选者。在哪里可以找到类似操作的示例代码以及如何将其集成到我的项目中。

public Bitmap rotateBitmap(Bitmap image, int angle) {
    if (image != null) {

        Matrix matrix = new Matrix();
        matrix.postRotate(angle, (image.getWidth()) / 2,
                (image.getHeight()) / 2);

        return Bitmap.createBitmap(image, 0, 0, image.getWidth(),
                image.getHeight(), matrix, true);
    }
    return null;
}

【问题讨论】:

  • 总是返回 outofmem 吗?你的位图有多大?
  • 不总是,但偶尔。我认为这是因为创建了副本。我使用 Picasso 库下载图像并调整其大小以适合半屏尺寸
  • @MiloslawSmyk 我的图像是下采样的,图像大小是 110 KB,所以它很小。无论如何要使用renderscript的ScriptInstric操作来做到这一点?
  • @pats 您是否正在寻找 90 度旋转 - stackoverflow.com/questions/12044674/… 或任意角度旋转(例如顺时针 27 度)
  • 是的,我已经试过了。但是设置scriptC的东西真的很困难。有没有办法在不设置脚本的情况下以 90 的倍数旋转。我的意思是使用 scriptintric 并且仅使用 java

标签: android bitmap renderscript


【解决方案1】:

基本上旋转位图是在不使用额外内存的情况下旋转二维数组的任务。这是使用 RenderScript 的正确实现:Android: rotate image without loading it to memory

但如果您只想显示旋转的位图,则不需要这样做。您可以简单地扩展 ImageView 并在绘制时旋转 Canvas

canvas.save();
canvas.rotate(angle, X + (imageW / 2), Y + (imageH / 2));
canvas.drawBitmap(imageBmp, X, Y, null);
canvas.restore();

ScriptIntrinsic 怎么样,因为它只是一个用于常见操作的内置 RenderScript 内核,你不能在已经实现的功能之上做任何事情:ScriptIntrinsic3DLUT, ScriptIntrinsicBLAS, ScriptIntrinsicBlend, ScriptIntrinsicBlur, ScriptIntrinsicColorMatrix, ScriptIntrinsicConvolve3x3, ScriptIntrinsicConvolve5x5, ScriptIntrinsicHistogram, ScriptIntrinsicLUT, ScriptIntrinsicResize, ScriptIntrinsicYuvToRGB。它们目前不包含旋转位图的功能,因此您应该创建自己的 ScriptC 脚本。

【讨论】:

  • 谢谢,我已经尝试过该链接中提出的 rederscript 算法。考虑到构建工具中版本的混乱,设置 scriptC 的东西真的很难。我想知道有没有办法使用 scriptintric 和 javacode 避免 scriptC 进行旋转
【解决方案2】:

试试这个代码..

private Bitmap RotateImage(Bitmap _bitmap, int angle) {

    Matrix matrix = new Matrix();
    matrix.postRotate(angle);
    _bitmap = Bitmap.createBitmap(_bitmap, 0, 0, _bitmap.getWidth(), _bitmap.getHeight(), matrix, true);
    return _bitmap;
}

从图库中选择图片时使用此代码。

像这样..

     File _file = new File(file_name);
     BitmapFactory.Options options = new BitmapFactory.Options();
     options.inSampleSize = 1;
     Bitmap bitmap = BitmapFactory.decodeFile(file_name, options);

     try {
            ExifInterface exif = new ExifInterface(file_name);
            int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 1);
            if (orientation == ExifInterface.ORIENTATION_ROTATE_90) {
                bitmap = RotateImage(bitmap, 90);
            } else if (orientation ==ExifInterface.ORIENTATION_ROTATE_270) {
                bitmap = RotateImage(bitmap, 270);

            }

        } catch (Exception e) {
            e.printStackTrace();
        }
      image_holder.setImageBitmap(bitmap);

【讨论】:

  • 感谢您的回复,但我没有看到太大的区别,因为我在从方法返回新图像后将新图像分配给输入图像
  • 检查差异,首先从前置摄像头拍摄图像,然后使用该功能和不使用该功能进行检查。
  • 哦,对不起,我从网上下载了图片。
  • @pats 好的,当您从前置摄像头捕获图像时,一次旋转图像保存,这就是使用此功能的原因。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-31
  • 1970-01-01
相关资源
最近更新 更多