为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

慕森王 2023-03-17 14:11:39
我完全理解“过早的优化是万恶之源”。但是,我已经到了一个地步,我认为我想做的优化不能再被认为是“过早的”。我正在编写一个 Android 应用程序,除其他外,它从 USB 设备流式传输实时图像提要,使用 OpenCV 执行一些图像处理,将帧转换为位图,然后将该位图实时渲染到 SurfaceView。我让一切正常,(实时提要正确呈现到 SurfaceView)并且 Android Studio 的“Profiler”工具表明我已经很好地完成了内存管理(请注意,垃圾收集器不会在下面显示的 10 秒内运行一次) :但是,因为我流式传输的图像分辨率较低 (320x180),当我将它直接渲染到 SurfaceView 时,它实际上最终在设备屏幕上非常小。因此,我决定在将位图渲染到屏幕之前将位图缩放到适合 SurfaceView 的最大尺寸。然而,在这样做之后,我惊恐地发现内存使用图现在看起来很可怕!(垃圾收集器每秒运行不止一次!)以下是相关的代码片段:在缩放位图之前(清理内存图):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()是罪魁祸首。有谁知道另一种方法来完成同样的事情,而不是让垃圾收集器赚钱?
查看完整描述

1 回答

?
千万里不及你

TA贡献1784条经验 获得超9个赞

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

我正在查看canvas.drawBitmap(位图位图、Rect src、Rect dst、Paint paint)——请注意,它采用源矩形和目标矩形。

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


查看完整回答
反对 回复 2023-03-17
  • 1 回答
  • 0 关注
  • 67 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信