java - Bitmap.createScaledBitmap 的更多内存优化版本?

标签 java android bitmap surfaceview

我完全理解“过早的优化是万恶之源。”但是,我已经到了这样的地步:我相信我想做的优化不再被认为是“过早的优化” ”。

我正在编写一个 Android 应用程序,除其他外,它还可以从 USB 设备流式传输实时图像,使用 OpenCV 执行一些图像处理,将帧转换为位图,然后将该位图实际渲染到 SurfaceView时间。

我让一切正常工作,(实时提要正确呈现到 SurfaceView)并且 Android Studio 的“Profiler”工具表明我已经很好地完成了内存管理(请注意,垃圾收集器不会运行一次下面显示的 10 秒):

enter image description here

但是,由于我流式传输的图像分辨率较低 (320x180),因此当我将其直接渲染到 SurfaceView 时,它实际上在设备屏幕上的物理尺寸非常小。

因此,我决定在将位图渲染到屏幕之前将其缩放到适合 SurfaceView 的最大尺寸。然而,这样做之后,我惊讶地发现内存使用图现在看起来很可怕! (垃圾收集器每秒运行多次!)

enter image description here

以下是相关代码 fragment :

  • 缩放位图之前(清理内存图):

    canvas = getHolder().lockCanvas();
    openCvMat = frameQueue.take();
    Utils.matToBitmap(openCvMat, bitmapFromMat);
    mat.release();
    canvas.drawColor(Color.BLACK);
    canvas.drawBitmap(bitmapFromMat, 0, 0, null);
    getHolder().unlockCanvasAndPost(canvas);
    
  • 缩放位图后(可怕的内存图):

    canvas = getHolder().lockCanvas();
    openCvMat = frameQueue.take();
    Utils.matToBitmap(openCvMat, bitmapFromMat);
    mat.release();
    canvas.drawColor(Color.BLACK);
    Bitmap scaled = scaleBitmapToViewport(bitmapFromMat);
    canvas.drawBitmap(scaled, 0, 0, null);
    scaled.recycle();
    getHolder().unlockCanvasAndPost(canvas);
    
  • scaleBitmapToViewport()方法:

    private Bitmap scaleBitmapToViewport(Bitmap bitmap)
    {
        //Landscape
        if((canvas.getHeight() * aspectRatio) < canvas.getWidth())
        {
            return Bitmap.createScaledBitmap(bitmap, (int) Math.round(canvas.getHeight() * aspectRatio), canvas.getHeight(), true);
        }
        else //Portrait
        {
            return Bitmap.createScaledBitmap(bitmap, canvas.getWidth(), (int) Math.round(canvas.getWidth() / aspectRatio), true);
        }
    }
    

所以看来 Bitmap.createScaledBitmap() 是罪魁祸首。有谁知道另一种方法可以完成同样的任务,并且不会给垃圾收集器带来麻烦?

最佳答案

不要像您正在做的那样缩放位图本身 - 绘图时不能缩放吗?

我正在看canvas.drawBitmap (位图位图、矩形 src、矩形 dst、Paint 绘画)- 请注意,它同时采用源矩形和目标矩形。

您需要将源设置为(小)图像尺寸,将目标设置为表面尺寸。

关于java - Bitmap.createScaledBitmap 的更多内存优化版本?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56962606/

相关文章:

Android:使用Zxing生成的二维码有边距(不适合该区域)

java - 定位一个模式,如果没有找到,则定位一个越来越小的子集

java - 具有 CompletableFuture 的 Vertx HTTPClient 阻止回调线程

java - 如何显示任何菜单 fragment (setVisible :ON) while i press button login

android - 在原始 Activity 中打开一个新 Activity 并完成原始 Activity

android - 媒体录音机 录音电话有时无法录制对方的声音

java - PlayFramework (2.5.x) 不绑定(bind)来自表单的数据,返回带有空字段的 Ojbect

android - 带有Git的Android Studio Gradle外部目录/库

android - 向临时缓存文件android写入和读取位图时出错?

android - GC 太多会影响设备电池显着下降吗?