表面支架上的凸轮图片,绘制:由于表面类型而出现异常

发布于 2024-11-15 04:08:26 字数 3702 浏览 1 评论 0原文

我使用 SurfaceViewSurfaceHolder 在我的测试应用中开始相机预览。

public class TextLocatorActivity extends Activity {

    private Preview pvw;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);

        pvw = new Preview(this);
        setContentView(pvw);        
    }   

我想使用 CameraPreview(随 SDK 版本 7 的 SDK 示例一起提供)。单击 UI 即可拍摄照片。这是 Preview 类:

public class Preview extends SurfaceView implements OnClickListener, SurfaceHolder.Callback {

SurfaceHolder holder;
Camera cam; 

final static String TAG = "TextLocator:Preview";

Preview(Context context) {
    super(context);

    holder = getHolder();
    holder.addCallback(this);
    this.setOnClickListener(this);
    // seems to be required (although the docs state, this enum is deprecated, as the type will be chosen automatically...
    holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}

public void surfaceCreated(SurfaceHolder holder) {
    cam = Camera.open();
    try {
        Camera.Parameters params = cam.getParameters();
        params.set("orientation", "landscape");
        Camera.Size bestSize = getBestPreviewSize(480, 320);
        params.setPreviewSize(bestSize.width, bestSize.height);
        cam.setParameters(params);
        // where to draw:
        cam.setPreviewDisplay(holder);
    } catch (IOException exception) {
        cam.release();
        cam = null;
        // TODO: add more exception handling logic here
    }
}

private Camera.Size getBestPreviewSize(int width, int height)
{
    // checks for supported sizes close to the demanded values - implemented.
}


public void surfaceDestroyed(SurfaceHolder holder) {
    cam.stopPreview();
    cam.release();
    cam = null;
}

public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
    Camera.Parameters parameters = cam.getParameters();
    parameters.setPreviewSize(w, h);

    cam.setParameters(parameters);
    cam.startPreview();
}

Camera.PictureCallback picCallback = new Camera.PictureCallback() {

    public void onPictureTaken(byte[] bytes, Camera arg1) {
        synchronized(holder) {
                Canvas c = null;    

                try {
                    c = holder.lockCanvas();                

                    Paint paint = new Paint();
                    paint.setAntiAlias(false);
                    paint.setARGB(200, 120, 180, 0);

                    c.drawLine(10, 10, c.getWidth() - 10, c.getHeight() - 10, paint);
                }
                catch (Exception e) {
                    Log.d(TAG, "Exception: " + e.getMessage());
                    // IllegalArguementException Surface Type is SURFACE_TYPE_PUSH_BUFFERS
                }
                finally {       
                    holder.unlockCanvasAndPost(c);  
                }
            }
    }
};

public void onClick(View v) 
{
    cam.takePicture(null, null, picCallback);    
}

}

接下来,我尝试对 SurfaceHolder 的相应 Canvas 进行一些额外的绘制。因此我调用 canvas =holder.lockCanvas()。这将导致 IllegalArgumentException 并显示以下消息:

Surface type is SURFACE_TYPE_PUSH_BUFFERS

现在,文档指出这些表面类型已被弃用,设置的值将被忽略。但是,只有当我将类型设置为该特定值时,相机预览才有效。

如何实现在显示拍摄照片的 SurfaceViewCanvas 上绘图?或者应该将其放在不同的图层/视图上?

I'm using a SurfaceView with a SurfaceHolder to start off with a camera preview in my test app.

public class TextLocatorActivity extends Activity {

    private Preview pvw;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);

        pvw = new Preview(this);
        setContentView(pvw);        
    }   

I want to use the CameraPreview (comes with the SDK Samples for SDK version 7). A click on the UI takes a picture. Here's the Preview class:

public class Preview extends SurfaceView implements OnClickListener, SurfaceHolder.Callback {

SurfaceHolder holder;
Camera cam; 

final static String TAG = "TextLocator:Preview";

Preview(Context context) {
    super(context);

    holder = getHolder();
    holder.addCallback(this);
    this.setOnClickListener(this);
    // seems to be required (although the docs state, this enum is deprecated, as the type will be chosen automatically...
    holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}

public void surfaceCreated(SurfaceHolder holder) {
    cam = Camera.open();
    try {
        Camera.Parameters params = cam.getParameters();
        params.set("orientation", "landscape");
        Camera.Size bestSize = getBestPreviewSize(480, 320);
        params.setPreviewSize(bestSize.width, bestSize.height);
        cam.setParameters(params);
        // where to draw:
        cam.setPreviewDisplay(holder);
    } catch (IOException exception) {
        cam.release();
        cam = null;
        // TODO: add more exception handling logic here
    }
}

private Camera.Size getBestPreviewSize(int width, int height)
{
    // checks for supported sizes close to the demanded values - implemented.
}


public void surfaceDestroyed(SurfaceHolder holder) {
    cam.stopPreview();
    cam.release();
    cam = null;
}

public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
    Camera.Parameters parameters = cam.getParameters();
    parameters.setPreviewSize(w, h);

    cam.setParameters(parameters);
    cam.startPreview();
}

Camera.PictureCallback picCallback = new Camera.PictureCallback() {

    public void onPictureTaken(byte[] bytes, Camera arg1) {
        synchronized(holder) {
                Canvas c = null;    

                try {
                    c = holder.lockCanvas();                

                    Paint paint = new Paint();
                    paint.setAntiAlias(false);
                    paint.setARGB(200, 120, 180, 0);

                    c.drawLine(10, 10, c.getWidth() - 10, c.getHeight() - 10, paint);
                }
                catch (Exception e) {
                    Log.d(TAG, "Exception: " + e.getMessage());
                    // IllegalArguementException Surface Type is SURFACE_TYPE_PUSH_BUFFERS
                }
                finally {       
                    holder.unlockCanvasAndPost(c);  
                }
            }
    }
};

public void onClick(View v) 
{
    cam.takePicture(null, null, picCallback);    
}

}

Next I'm trying to do some additional painting to the corresponding Canvas of the SurfaceHolder. Therefore I'm calling canvas = holder.lockCanvas(). This will result in an IllegalArgumentException with the Message:

Surface type is SURFACE_TYPE_PUSH_BUFFERS

Now, docs state that those Surface Types are deprecated, the value set will be ignored. However, the camera preview only works, if I set the type to this specific value.

How can I achieve drawing on the Canvas of the SurfaceView the picture taken is displayed in? Or should that be put on a different layer/view?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

倾城°AllureLove 2024-11-22 04:08:26

您无法同时显示相机预览和使用画布进行绘制。你必须做其中之一。

You cannot both display the camera preview and draw with a Canvas. You have to do one or the other.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文