我正在使用从处理我的视频输入的TextureView获得的Bitmap图像进行一些图像处理测试。在我的测试中,我注意到TextureView.getBitmap(Bitmap)运行的时间,有时在执行之间会有所不同。
为了演示此问题,我从TextureView API reference修改了一个示例。在下面的代码中,我使用相机作为TextureView的输入,抓取位图并将其渲染到SurfaceView,测量它需要多少时间。我在一对运行Android 4.2.2的Nexus 7设备上进行了测试。我实际上已经注意到两种模式,一种是慢速的,一种是快速的。
当执行“慢”时,getBitmap(Bitmap)大约需要20ms。 当执行“快”时,getBitmap(Bitmap)大约需要15ms。
大多数情况下,该应用程序以“慢”模式运行。如果我摆弄设备或重新编译/重新安装应用程序,有时我会让它以“快速”模式工作。但之后它将再次缓慢运行。程序重启后,速度只会发生变化,永远不会在执行过程中发生变化。
顺便说一下,将Bitmap转储到SurfaceView只需要大约8ms:我想知道为什么从TextureView中取出Bitmap需要的时间超过两倍。
问题:
谢谢。
- 圣拉斐尔
PS:我已经在Android开发者谷歌集团中发布了此消息,但似乎自上周以来它一直处于适度调整状态。抱歉交叉发布。
编辑:
我为那些希望更轻松地尝试它的人添加了sample project给GitHub:
活动:
import java.io.IOException;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.SurfaceTexture;
import android.hardware.Camera;
import android.os.Bundle;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.TextureView;
public class LiveCameraActivity extends Activity implements TextureView.SurfaceTextureListener {
private Camera mCamera;
private TextureView mTextureView;
private SurfaceView mSurfaceView;
private final int imgW = 640;
private final int imgH = 480;
private Bitmap bmp = Bitmap.createBitmap(imgW, imgH, Bitmap.Config.ARGB_8888);
private Canvas canvas = new Canvas(bmp);
private Paint paint1 = new Paint();
private SurfaceHolder mSurfaceHolder;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main2);
mSurfaceView = (SurfaceView) findViewById(R.id.surfaceview);
mSurfaceHolder = mSurfaceView.getHolder();
mTextureView = (TextureView) findViewById(R.id.textureview);
mTextureView.setSurfaceTextureListener(this);
final int textSize = 24;
paint1.setColor(0xff00ffff);
paint1.setTextSize(textSize);
}
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
mCamera = Camera.open(Camera.getNumberOfCameras()-1);
Camera.Parameters parameters = mCamera.getParameters();
parameters.setPreviewSize(imgW, imgH);
mCamera.setParameters(parameters);
try {
mCamera.setPreviewTexture(surface);
mCamera.startPreview();
} catch (IOException ioe) {
// Something bad happened
}
}
public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
// Ignored, Camera does all the work for us
}
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
mCamera.stopPreview();
mCamera.release();
return true;
}
public void onSurfaceTextureUpdated(SurfaceTexture surface) {
// Invoked every time there's a new Camera preview frame
long time0 = System.currentTimeMillis();
mTextureView.getBitmap(bmp);
long time1 = System.currentTimeMillis() - time0;
final Canvas c = mSurfaceHolder.lockCanvas();
if ( c != null) {
canvas.drawText("getBmp= " + time1, 10, 40, paint1);
c.drawBitmap(bmp, 0, 0, null);
mSurfaceHolder.unlockCanvasAndPost(c);
}
long total = System.currentTimeMillis() - time0;
long time2 = total -time1;
Log.i("onFrame", "timing: getBmp= " + time1 + " blit= " + time2 + " total= " + total);
}
}
布局:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin" >
<SurfaceView
android:id="@+id/surfaceview"
android:layout_width="640px"
android:layout_height="480px" />
<TextureView
android:id="@+id/textureview"
android:layout_width="640px"
android:layout_height="480px" />
</LinearLayout>