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

rdo*_*eui 7 android surfaceview surfaceholder

我使用的是SurfaceView具有SurfaceHolder与在我的测试应用程序相机预览开始.

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);        
    }   
Run Code Online (Sandbox Code Playgroud)

我想使用CameraPreview(随SDK版本7的SDK Samples一起提供).点击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);    
}
Run Code Online (Sandbox Code Playgroud)

}

接下来我正在尝试做一些额外的绘画到相应CanvasSurfaceHolder.所以我在打电话canvas = holder.lockCanvas().这将导致IllegalArgumentException与消息:

Surface type is SURFACE_TYPE_PUSH_BUFFERS
Run Code Online (Sandbox Code Playgroud)

现在,docs声明不推荐使用这些Surface类型,将忽略值集.但是,如果我将类型设置为此特定值,则相机预览仅起作用.

我如何能实现在图纸上Canvas的的SurfaceView拍摄的画面显示在?或者应该将其放在不同的图层/视图上?

Rom*_*Guy 5

您不能同时显示相机预览并使用画布进行绘制.你必须做一个或另一个.

  • 没有什么可说的,当使用SurfaceView时,相关的Surface只能用于一种类型的渲染:视频,GPU或软件.一旦选择了一种类型的渲染,它就不能用于其他类型.这都是关于内存中缓冲区的格式以及存储内存的位置. (2认同)