【问题标题】:How to process efficiently with ImageView in a video render case?如何在视频渲染案例中使用 ImageView 高效处理?
【发布时间】:2016-08-31 20:54:21
【问题描述】:

我正在开发一个视频流应用程序。这是一个特殊情况,我需要手动处理每一帧(从网络访问到解码和其他处理)。在我所有过程的最后,对于每一帧,我都有一个 byte[] 包含 ARGB_8888 编码图像。

现在,我以这种方式绘制每一帧(假设 width = 1280 和 height = 720,data 是我的byte[]包含框架,imageView 是我的ImageView 容器)

// Step 1: reception and treatments
// After that, data contains the frame bytes;

// Step 2: bitmap creation
Bitmap toDraw = Bitmap.createBitmap(1280, 720, Bitmap.Config.ARGB_8888);
toDraw.copyPixelsFromBuffer(ByteBuffer.wrap(data));

// Step 3: draw the bitmap
imageView.post(new Runnable() {

    @Override
    public void run()
    {
        imageView.setImageBitmap(toDraw);
    }
});

一切正常,没问题。但是我有很多 GC,我真的不喜欢每次为每个相同大小的帧创建一个新的Bitmap!所以我需要知道如何优化我的帧渲染?我知道我只能在第一次调用createBitmap 然后只使用copyPixelsFromBuffer 来填充它(即使它制作了一个副本并且我不喜欢它但它更好)。我想到了一个直观的解决方案,但我不知道这是否可能:

如果我只在第一次创建和绘制Bitmap,然后我从imageView 检索对像素的引用并修改它,或者直接修改它,或者将我的data 作为参考,该怎么办?我搜索了DrawingCache,但没有找到解决方案。

否则,有什么比这段代码做得更好的想法(更好我的意思是内存友好和更快)?问题是:提供我已经解码的byte[] 数据(对于每一帧),快速更新我的imageView 的最佳方法是什么。


编辑:我只看到that。我会测试并继续调查。

【问题讨论】:

    标签: android performance video imageview android-bitmap


    【解决方案1】:

    您可以仅在需要时创建位图,如果它为空或大小不合适

    Bitmap mBitmap;
    
    private void someMethod(){
    
        if(mBitmap == null || !isBitmapSizeOk(mBitmap)){
            if(mBitmap != null) mBitmap.recycle();
    
            mBitmap = Bitmap.createBitmap(1280, 720, Bitmap.Config.ARGB_8888);
            // call it only when the Bitmap instance changes
            imageView.setImageBitmap(mBitmap); 
        }
    
        mBitmap.copyPixelsFromBuffer(ByteBuffer.wrap(data));
    
        // Step 3: draw the bitmap
        imageView.post(new Runnable() {
    
            @Override
            public void run(){    
                imageView.invalidate();       
            }
        });
    }
    

    setImageBitmap(mBitmap)只能在创建Bitmap时调用,避免每次都调用

    【讨论】:

    • 感谢您的回答,但我知道这一点,我将其写在代码示例的底部 > “我知道我只能在第一次调用 createBitmap 然后只使用 copyPixelsFromBuffer”
    • 哦,我明白了,那我恐怕不明白是什么问题
    • 我想知道是否有可能避免为每一帧调用setImageBitmap()并访问当前显示的位图缓冲区来修改它。
    • 当然,你不需要每次都调用它但你仍然需要通知ImageView它必须重新绘制自己,请看更新答案:)
    • 好的,谢谢!默认情况下,位图是持久的,只有调用 recycle() 才能让我们删除它?
    猜你喜欢
    • 2010-10-03
    • 2011-04-23
    • 1970-01-01
    • 2021-11-07
    • 2022-01-06
    • 2015-08-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多