如何在视频渲染案例中使用 ImageView 进行高效处理?
How to process efficiently with ImageView in a video render case?
我正在开发一个视频流应用程序。这是一个特殊情况,我需要手动处理每一帧(从网络访问到解码和其他处理)。在我所有过程的最后,对于每一帧,我都有一个包含 ARGB_8888
编码图像的 byte[]
。
现在,我以这种方式绘制每一帧(假设 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
但没有找到解决方案。
否则,有没有比这段代码做得更好的想法(更好的意思是内存友好且速度更快)?问题是:什么是快速更新我的 imageView
提供我已经解码的 byte[]
数据(对于每一帧)的最佳方法。
编辑:我刚看到 that。我会测试并继续调查。
您可以仅在需要时创建位图,如果它为空或大小不合适
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();
}
});
}
可以只在创建Bitmap时调用setImageBitmap(mBitmap),避免每次都调用它,但是ImageView需要知道它必须自己重绘,你可以调用invalidate()
我正在开发一个视频流应用程序。这是一个特殊情况,我需要手动处理每一帧(从网络访问到解码和其他处理)。在我所有过程的最后,对于每一帧,我都有一个包含 ARGB_8888
编码图像的 byte[]
。
现在,我以这种方式绘制每一帧(假设 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
但没有找到解决方案。
否则,有没有比这段代码做得更好的想法(更好的意思是内存友好且速度更快)?问题是:什么是快速更新我的 imageView
提供我已经解码的 byte[]
数据(对于每一帧)的最佳方法。
编辑:我刚看到 that。我会测试并继续调查。
您可以仅在需要时创建位图,如果它为空或大小不合适
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();
}
});
}
可以只在创建Bitmap时调用setImageBitmap(mBitmap),避免每次都调用它,但是ImageView需要知道它必须自己重绘,你可以调用invalidate()