ApiDemo 学习 CameraPreview 和 Clipping

来源:互联网 发布:unity3d粒子系统教程 编辑:程序博客网 时间:2024/05/01 18:22
public class CameraPreview extends Activity {    private Preview mPreview;    Camera mCamera;    int numberOfCameras;    int cameraCurrentlyLocked;    // The first rear facing camera    int defaultCameraId;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        // Hide the window title.        requestWindowFeature(Window.FEATURE_NO_TITLE);        getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);        // Create a RelativeLayout container that will hold a SurfaceView,        // and set it as the content of our activity.        mPreview = new Preview(this);        setContentView(mPreview);        // Find the total number of cameras available        numberOfCameras = Camera.getNumberOfCameras();        // Find the ID of the default camera        CameraInfo cameraInfo = new CameraInfo();        for (int i = 0; i < numberOfCameras; i++) {                Camera.getCameraInfo(i, cameraInfo);                if (cameraInfo.facing == CameraInfo.CAMERA_FACING_BACK) {//h后面的摄像头                    defaultCameraId = i;                }            }    }    @Override    protected void onResume() {        super.onResume();        // Open the default i.e. the first rear facing camera.        mCamera = Camera.open();        cameraCurrentlyLocked = defaultCameraId;        mPreview.setCamera(mCamera);    }    @Override    protected void onPause() {        super.onPause();        // Because the Camera object is a shared resource, it's very        // important to release it when the activity is paused.        if (mCamera != null) {            mPreview.setCamera(null);            mCamera.release();            mCamera = null;        }    }    @Override    public boolean onCreateOptionsMenu(Menu menu) {        // Inflate our menu which can gather user input for switching camera        MenuInflater inflater = getMenuInflater();        inflater.inflate(R.menu.camera_menu, menu);        return true;    }    @Override    public boolean onOptionsItemSelected(MenuItem item) {        // Handle item selection        switch (item.getItemId()) {        case R.id.switch_cam:            // check for availability of multiple cameras            if (numberOfCameras == 1) {                AlertDialog.Builder builder = new AlertDialog.Builder(this);                builder.setMessage(this.getString(R.string.camera_alert))                       .setNeutralButton("Close", null);                AlertDialog alert = builder.create();                alert.show();                return true;            }            // OK, we have multiple cameras.            // Release this camera -> cameraCurrentlyLocked            if (mCamera != null) {                mCamera.stopPreview();                mPreview.setCamera(null);                mCamera.release();                mCamera = null;            }            // Acquire the next camera and request Preview to reconfigure            // parameters.            mCamera = Camera                    .open((cameraCurrentlyLocked + 1) % numberOfCameras);            cameraCurrentlyLocked = (cameraCurrentlyLocked + 1)                    % numberOfCameras;            mPreview.switchCamera(mCamera);            // Start the preview            mCamera.startPreview();            return true;        default:            return super.onOptionsItemSelected(item);        }    }}// ----------------------------------------------------------------------/** * A simple wrapper around a Camera and a SurfaceView that renders a centered preview of the Camera * to the surface. We need to center the SurfaceView because not all devices have cameras that * support preview sizes at the same aspect ratio as the device's display. */class Preview extends ViewGroup implements SurfaceHolder.Callback {    private final String TAG = "Preview";    SurfaceView mSurfaceView;    SurfaceHolder mHolder;    Size mPreviewSize;    List<Size> mSupportedPreviewSizes;    Camera mCamera;    Preview(Context context) {        super(context);        mSurfaceView = new SurfaceView(context);        addView(mSurfaceView);        // Install a SurfaceHolder.Callback so we get notified when the        // underlying surface is created and destroyed.        mHolder = mSurfaceView.getHolder();        mHolder.addCallback(this);        mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);    }    public void setCamera(Camera camera) {        mCamera = camera;        if (mCamera != null) {            //照相机支持的 大小 可能有不同的相机            mSupportedPreviewSizes = mCamera.getParameters().getSupportedPreviewSizes();            requestLayout();        }    }//切换 camera    public void switchCamera(Camera camera) {       setCamera(camera);       try {           camera.setPreviewDisplay(mHolder);       } catch (IOException exception) {           Log.e(TAG, "IOException caused by setPreviewDisplay()", exception);       }       Camera.Parameters parameters = camera.getParameters();       parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height);        requestLayout();       camera.setParameters(parameters);    }    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        // We purposely disregard child measurements because act as a        // wrapper to a SurfaceView that centers the camera preview instead        // of stretching it.        final int width = resolveSize(getSuggestedMinimumWidth(), widthMeasureSpec);        final int height = resolveSize(getSuggestedMinimumHeight(), heightMeasureSpec);        setMeasuredDimension(width, height);        if (mSupportedPreviewSizes != null) {            mPreviewSize = getOptimalPreviewSize(mSupportedPreviewSizes, width, height);        }    }    @Override    protected void onLayout(boolean changed, int l, int t, int r, int b) {        if (changed && getChildCount() > 0) {            final View child = getChildAt(0);            final int width = r - l;            final int height = b - t;            int previewWidth = width;            int previewHeight = height;            if (mPreviewSize != null) {                previewWidth = mPreviewSize.width;                previewHeight = mPreviewSize.height;            }            // Center the child SurfaceView within the parent.            //让surface居中 还要判断是横屏还是竖屏            if (width * previewHeight > height * previewWidth) {                final int scaledChildWidth = previewWidth * height / previewHeight;                child.layout((width - scaledChildWidth) / 2, 0,                        (width + scaledChildWidth) / 2, height);            } else {                final int scaledChildHeight = previewHeight * width / previewWidth;                child.layout(0, (height - scaledChildHeight) / 2,                        width, (height + scaledChildHeight) / 2);            }        }    }    public void surfaceCreated(SurfaceHolder holder) {        // The Surface has been created, acquire the camera and tell it where        // to draw.        try {            if (mCamera != null) {                mCamera.setPreviewDisplay(holder);            }        } catch (IOException exception) {            Log.e(TAG, "IOException caused by setPreviewDisplay()", exception);        }    }    public void surfaceDestroyed(SurfaceHolder holder) {        // Surface will be destroyed when we return, so stop the preview.        if (mCamera != null) {            mCamera.stopPreview();        }    }  //设置 camera的 高度和宽度为 屏幕    private Size getOptimalPreviewSize(List<Size> sizes, int w, int h) {        final double ASPECT_TOLERANCE = 0.1;        double targetRatio = (double) w / h;        if (sizes == null) return null;        Size optimalSize = null;        double minDiff = Double.MAX_VALUE;        int targetHeight = h;        // Try to find an size match aspect ratio and size        for (Size size : sizes) {            double ratio = (double) size.width / size.height;            if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) continue;            if (Math.abs(size.height - targetHeight) < minDiff) {                optimalSize = size;                minDiff = Math.abs(size.height - targetHeight);            }        }        // Cannot find the one match the aspect ratio, ignore the requirement        if (optimalSize == null) {            minDiff = Double.MAX_VALUE;            for (Size size : sizes) {                if (Math.abs(size.height - targetHeight) < minDiff) {                    optimalSize = size;                    minDiff = Math.abs(size.height - targetHeight);                }            }        }        return optimalSize;    }   //开始设置camera的图像    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {        // Now that the size is known, set up the camera parameters and begin        // the preview.        Camera.Parameters parameters = mCamera.getParameters();        parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height);        requestLayout();        mCamera.setParameters(parameters);        mCamera.startPreview();    }}



import android.graphics.*;import android.os.Bundle;import android.view.View;//图形的拼接public class Clipping extends GraphicsActivity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(new SampleView(this));    }    private static class SampleView extends View {        private Paint mPaint;        private Path mPath;        public SampleView(Context context) {            super(context);            setFocusable(true);            mPaint = new Paint();            mPaint.setAntiAlias(true);            mPaint.setStrokeWidth(6);            mPaint.setTextSize(16);            mPaint.setTextAlign(Paint.Align.RIGHT); //设置paint 绘制文字从右边开始写            mPath = new Path();        }        private void drawScene(Canvas canvas) {            canvas.clipRect(0, 0, 100, 100); //在背景上 "抠一个方形的洞",填充为白色            canvas.drawColor(Color.WHITE);            mPaint.setColor(Color.RED);            canvas.drawLine(0, 0, 100, 100, mPaint);            mPaint.setColor(Color.GREEN);            canvas.drawCircle(30, 70, 30, mPaint);            mPaint.setColor(Color.BLUE);            canvas.drawText("Clipping", 100, 30, mPaint);        }        @Override protected void onDraw(Canvas canvas) {            canvas.drawColor(Color.GRAY);            canvas.save();            canvas.translate(10, 10); //移动到10,10 绘制第一个图案            drawScene(canvas);            canvas.restore();            canvas.save(); //开始一个新的图案绘制            canvas.translate(160, 10);            canvas.clipRect(10, 10, 90, 90); //抠出外部的矩形            canvas.clipRect(30, 30, 70, 70, Region.Op.DIFFERENCE);//两个矩形的不同的地方  如果是INTERSECT(交叉)就可以显示中心的矩形,两个矩形的相交            drawScene(canvas);            canvas.restore();            canvas.save();            canvas.translate(10, 160);            mPath.reset();            canvas.clipPath(mPath); // makes the clip empty            mPath.addCircle(50, 50, 50, Path.Direction.CCW);//矩形圆形的交集            canvas.clipPath(mPath, Region.Op.REPLACE);            drawScene(canvas);            canvas.restore();            canvas.save();            canvas.translate(160, 160);            canvas.clipRect(0, 0, 60, 60);            canvas.clipRect(40, 40, 100, 100, Region.Op.UNION); // 两个矩形的联合集            drawScene(canvas);            canvas.restore();            canvas.save();            canvas.translate(10, 310);            canvas.clipRect(0, 0, 60, 60);            canvas.clipRect(40, 40, 100, 100, Region.Op.XOR); //两个矩形的联合 但是去除他们的交集            drawScene(canvas);            canvas.restore();            canvas.save();            canvas.translate(160, 310);            canvas.clipRect(0, 0, 60, 60);            canvas.clipRect(40, 40, 100, 100, Region.Op.REVERSE_DIFFERENCE);//下面矩形没有的那一部分            drawScene(canvas);            canvas.restore();        }    }}