startPreview 函数很慢,有解决办法吗?
问题:
我正在 Android 上制作一个应用程序,在拍摄图像时需要相机快速响应,我注意到应用程序的行为缓慢,在测量时间后我注意到函数 startPreview() 是问题的原因。
代码预览:
这是代码的必要部分(与问题相关)。
预览Google课程(自定义预览): 在应用程序启动时,调用 surfaceChanged,我设置了一些相机参数,然后调用了 startPreview
public class PreviewGoogle extends ViewGroup implements SurfaceHolder.Callback {
private final String TAG = "myapp1";
Camera mCamera;
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
try
{
// Now that the size is known, set up the camera parameters and begin
// the preview.
Camera.Parameters parameters = mCamera.getParameters();
parameters.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_INFINITY);
parameters.setWhiteBalance(Camera.Parameters.WHITE_BALANCE_AUTO);
parameters.setSceneMode(Camera.Parameters.SCENE_MODE_AUTO);
parameters.setJpegQuality(100);
parameters.setPictureSize(Globals.CAMERA_WIDTH, Globals.CAMERA_HEIGHT);
requestLayout();
mCamera.setParameters(parameters);
long before = System.currentTimeMillis();
mCamera.startPreview();
long after = System.currentTimeMillis();
Log.d(TAG, "PreviewGoogle, surfaceChanged: startPreview took " + (after - before) + " ms");
}
catch (Exception e) {
Log.d(TAG, "PreviewGoogle, surfaceChanged: " + e.getMessage());
}
}
}
PhotoShootActivity 类: 在这个类中,我调用了 startPreview rawImageCallback 因为我在 jpegCallback 中使用 BitmapFactory (不是必需的东西)
public class PhotoShootActivity extends Activity
{
private static final String TAG = "myapp1";
PreviewGoogle preview;
// Handles data for raw picture
PictureCallback rawCallback = new PictureCallback()
{
public void onPictureTaken(byte[] data, Camera camera)
{
try
{
long before = System.currentTimeMillis();
preview.getCamera().startPreview();
long after = System.currentTimeMillis();
Log.d(PhotoShootActivity.TAG, "PhotoShootActivity, rawCallback: preview started in " + (after - before) + " ms");
}
catch(Exception e)
{
Log.e(TAG, "PhotoShootActivity, rawCallback: " + e.getMessage());
}
}
};
}
计时器编号如下所示:
09-09 10:58:42.336: DEBUG/myapp1(21958): PhotoShootActivity, onCreate
**09-09 10:58:44.396: DEBUG/myapp1(21958): PreviewGoogle, surfaceChanged: startPreview took 1457 ms**
09-09 10:58:48.438: DEBUG/myapp1(21958): PhotoShootActivity, buttonCapture: Picture taken in 65ms
09-09 10:58:48.496: DEBUG/myapp1(21958): PhotoShootActivity, shutterCallback: Empty
**09-09 10:58:49.790: DEBUG/myapp1(21958): PhotoShootActivity, rawCallback: preview started in 662 ms**
第一个 startPreview 花了大约 1500ms,第二个 startPreview 花了大约 1500ms花了 662 毫秒!!!
搜索到的解决方案:
我正在寻找的问题不是完整的代码(只需提示我:)),我认为我可能会在预览中遗漏某些内容,并且我考虑过在这种情况下使用线程,但我还不熟悉 android-sdk (我 4 天前开始使用 android 编程)
问候...
Problem:
I'm making an application on android which requires a fast response from the camera while shooting images, I noticed a slow behavior from the application, after measuring the time I noticed that function startPreview() is the responsible of the problem.
Code Preview:
This is the necessary part of the code (related to the problem).
PreviewGoogle Class (the custom preview):
On the start of the application the surfaceChanged is called, I've set some camera parameters then called the startPreview
public class PreviewGoogle extends ViewGroup implements SurfaceHolder.Callback {
private final String TAG = "myapp1";
Camera mCamera;
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
try
{
// Now that the size is known, set up the camera parameters and begin
// the preview.
Camera.Parameters parameters = mCamera.getParameters();
parameters.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_INFINITY);
parameters.setWhiteBalance(Camera.Parameters.WHITE_BALANCE_AUTO);
parameters.setSceneMode(Camera.Parameters.SCENE_MODE_AUTO);
parameters.setJpegQuality(100);
parameters.setPictureSize(Globals.CAMERA_WIDTH, Globals.CAMERA_HEIGHT);
requestLayout();
mCamera.setParameters(parameters);
long before = System.currentTimeMillis();
mCamera.startPreview();
long after = System.currentTimeMillis();
Log.d(TAG, "PreviewGoogle, surfaceChanged: startPreview took " + (after - before) + " ms");
}
catch (Exception e) {
Log.d(TAG, "PreviewGoogle, surfaceChanged: " + e.getMessage());
}
}
}
PhotoShootActivity class: In this class I called the startPreview on the rawImageCallback because I'm using the BitmapFactory in the jpegCallback (not necessary thing)
public class PhotoShootActivity extends Activity
{
private static final String TAG = "myapp1";
PreviewGoogle preview;
// Handles data for raw picture
PictureCallback rawCallback = new PictureCallback()
{
public void onPictureTaken(byte[] data, Camera camera)
{
try
{
long before = System.currentTimeMillis();
preview.getCamera().startPreview();
long after = System.currentTimeMillis();
Log.d(PhotoShootActivity.TAG, "PhotoShootActivity, rawCallback: preview started in " + (after - before) + " ms");
}
catch(Exception e)
{
Log.e(TAG, "PhotoShootActivity, rawCallback: " + e.getMessage());
}
}
};
}
The Timer Numbers were like this:
09-09 10:58:42.336: DEBUG/myapp1(21958): PhotoShootActivity, onCreate
**09-09 10:58:44.396: DEBUG/myapp1(21958): PreviewGoogle, surfaceChanged: startPreview took 1457 ms**
09-09 10:58:48.438: DEBUG/myapp1(21958): PhotoShootActivity, buttonCapture: Picture taken in 65ms
09-09 10:58:48.496: DEBUG/myapp1(21958): PhotoShootActivity, shutterCallback: Empty
**09-09 10:58:49.790: DEBUG/myapp1(21958): PhotoShootActivity, rawCallback: preview started in 662 ms**
The first startPreview took ~1500ms and the second took 662 ms!!!
Searched solution:
The question I'm looking for is not a full code (just tip me :)), I've thought that I could missing something in the preview, and I thought about using threads in this case but I'm not familiar with android-sdk yet (I started with android programing 4 days ago)
Regards...
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
来自android文档:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
startPreview()
开始捕获并将预览帧绘制到屏幕上。在使用
setPreviewDisplay(SurfaceHolder)
或setPreviewTexture(SurfaceTexture)
提供表面之前,预览实际上不会启动。如果
setPreviewCallback(Camera.PreviewCallback)
、setOneShotPreviewCallback(Camera.PreviewCallback)
、或setPreviewCallbackWithBuffer(Camera.PreviewCallback)
被调用时,onPreviewFrame(byte[], Camera)
将在预览数据可用时被调用。~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
所以在你的评论中你说你决定使用
onPreviewFrame(byte[] , Camera)
,正如您在文档中看到的,它表示仅在预览数据可用时才调用它,这需要一些时间。尝试通过为相机提供纹理或预览显示来添加第一个选项。即,在您的
surfaceChanged(SurfaceHolderholder, int format, int w, int h)
方法中:看看这是否会产生影响。
From the android docs:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
startPreview()
Starts capturing and drawing preview frames to the screen. Preview will not actually start until a surface is supplied with
setPreviewDisplay(SurfaceHolder)
orsetPreviewTexture(SurfaceTexture)
.If
setPreviewCallback(Camera.PreviewCallback)
,setOneShotPreviewCallback(Camera.PreviewCallback)
, orsetPreviewCallbackWithBuffer(Camera.PreviewCallback)
were called,onPreviewFrame(byte[], Camera)
will be called when preview data becomes available.~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
So in your comment you said you decided to use
onPreviewFrame(byte[], Camera)
, as you can see in the docs, it says it is only called when the preview data becomes available, whihc takes some time. Try adding the first option by providing the camera with a texture or a preview display.Ie, in your
surfaceChanged(SurfaceHolder holder, int format, int w, int h)
method:See if that makes a difference.