Android 安卓相机片段预览

Android 安卓相机片段预览,android,android-fragments,android-camera,Android,Android Fragments,Android Camera,到目前为止,我有一个完整的工作代码,可以插入一个摄像头来查看前摄像头的预览 我现在要做的是让相机在片段中工作 完整代码: MainActivity.java public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.

到目前为止,我有一个完整的工作代码,可以插入一个摄像头来查看前摄像头的预览

我现在要做的是让相机在
片段中工作

完整代码:

MainActivity.java

public class MainActivity extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.fragment_main);

    getFragmentManager().beginTransaction().add(R.id.mainLayout, new CameraExtractionFragment()).commit();
}
}
public class CameraExtractionFragment extends Fragment {

private CameraExtraction mCameraExtraction;
Camera mCamera;
int mNumberOfCameras;
int cameraId;
int rotation;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    mCameraExtraction = new CameraExtraction(
            this.getActivity().getBaseContext(), 
            this.getActivity().getWindowManager().getDefaultDisplay().getRotation()
            );

    // Find the total number of cameras available
    mNumberOfCameras = Camera.getNumberOfCameras();

    // Find the ID of the rear-facing ("default") camera
    CameraInfo cameraInfo = new CameraInfo();
    for (int i = 0; i < mNumberOfCameras; i++) {
        Camera.getCameraInfo(i, cameraInfo);
        if (cameraInfo.facing == CameraInfo.CAMERA_FACING_FRONT) {
            cameraId = i;
        }
    }
}

 @Override
 public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)               {
     return mCameraExtraction;
 }

 @Override
public void onResume() {
    super.onResume();

    // Use mCurrentCamera to select the camera desired to safely restore
    // the fragment after the camera has been changed
    mCamera = Camera.open(cameraId);
    mCameraExtraction.setCamera(mCamera);
}

@Override
public void onPause() {
    super.onPause();

    if (mCamera != null)
    {
        mCamera.release();
    }
}


// Modo en el que se pinta la cámara: encajada por dentro o saliendo los bordes por fuera.
public enum CameraViewMode {

    /**
     * Inner mode
     */
    Inner,
    /**
     * Outer mode 
     */
    Outer
}
}
public class CameraExtraction extends ViewGroup implements SurfaceHolder.Callback {

 private final String TAG = "CameraExtraction";

Camera mCamera;
SurfaceHolder mHolder;
SurfaceView mSurfaceView;
int mNumberOfCameras;
int cameraId;
Rect desiredSize;
CameraViewMode cameraViewMode;
boolean mSurfaceCreated = false;
List<Size> mSupportedPreviewSizes;
int rotation;
Size mPreviewSize;

public CameraExtraction(Context context, int rotation) {
    super(context);

    this.rotation = rotation;

    mSurfaceView = new SurfaceView(context);

    addView(mSurfaceView);

    // Install a SurfaceHolder.Callback so we get notified when the
    mHolder = mSurfaceView.getHolder();
    mHolder.addCallback(this);
    mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

    cameraViewMode = CameraViewMode.Inner;
}

public void setCamera(Camera camera) {
    mCamera = camera;
    if (mCamera != null) {
        mSupportedPreviewSizes = mCamera.getParameters().getSupportedPreviewSizes();
        if (mSurfaceCreated) requestLayout();
    }
}

public void switchCamera(Camera camera) {
    setCamera(camera);
    try {
        camera.setPreviewDisplay(mHolder);
    } catch (IOException exception) {
        Log.e(TAG, "IOException caused by setPreviewDisplay()", exception);
    }
}

@SuppressLint("DrawAllocation")
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    if (mSurfaceView == null ||mSurfaceView.getHolder() == null) return;

    if (mSurfaceView.getHolder().getSurface() == null) {
        // preview surface does not exist
        return;
    }

    final int width = resolveSize(getSuggestedMinimumWidth(),
            widthMeasureSpec);
    final int height = resolveSize(getSuggestedMinimumHeight(),
            heightMeasureSpec);
    setMeasuredDimension(width, height);

    if (mSupportedPreviewSizes != null) {

        mPreviewSize = getNearestPreviewSize(mCamera.new Size(widthMeasureSpec,heightMeasureSpec));
    }

    if (mCamera != null) {
      Camera.Parameters parameters = mCamera.getParameters();
      parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height);

      mCamera.setParameters(parameters);
    }
}

@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
    if (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.
        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);
        }
    }       
}

@Override
public void surfaceCreated(SurfaceHolder holder) {
    mCamera = Camera.open(cameraId);        
}

@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,int height) {
    if (mSurfaceView == null || mSurfaceView.getHolder() == null) return;

            if (mSurfaceView.getHolder().getSurface() == null) {
                // preview surface does not exist
                return;
            }

            // set preview size and make any resize, rotate or
            // reformatting changes here
            Camera.Parameters param = mCamera.getParameters();
            Point previewSize = new Point(640,480);

            Camera.Size size = getNearestPreviewSize(mCamera.new Size(previewSize.x,previewSize.y));
            param.setPreviewSize(size.width, size.height);
            mCamera.setParameters(param);
            rotation = setCameraDisplayOrientation(cameraId, mCamera);

            // start preview with new settings
            try {
                mCamera.setPreviewCallback(new Camera.PreviewCallback() {

                    @Override
                    public void onPreviewFrame(byte[] data, Camera camera) {
                        // TODO Auto-generated method stub

                    }
                });
                mCamera.setPreviewDisplay(mSurfaceView.getHolder());
                mCamera.startPreview();

            } catch (Exception e) {
                Log.d("AndroidControlSurfaceView",
                        "Error starting camera preview: " + e.getMessage());
            }       
}

@Override
public void surfaceDestroyed(SurfaceHolder holder) {
    if (mCamera != null)
    {
        mCamera.stopPreview();
        mCamera.release();
    }
}


protected Rect getCameraViewSizeCompensated(Camera.Size cameraPreviewSize, Point hostViewSize) {
    Rect toReturn=null;

    float ratioWidth = hostViewSize.x / (float)cameraPreviewSize.width;
    float ratioHeight = hostViewSize.y / (float)cameraPreviewSize.height;

    switch (cameraViewMode){
    case Inner:
        if (ratioWidth < ratioHeight) {
            int newHeight = (int)(cameraPreviewSize.height*ratioWidth);
            int y = (hostViewSize.y - newHeight) / 2;
            toReturn = new Rect(0, y, hostViewSize.x, y+newHeight);
        } else {
            int newWidth = (int)(cameraPreviewSize.width*ratioHeight);
            int x = (hostViewSize.x - newWidth) / 2;
            toReturn = new Rect(x, 0, x+newWidth,hostViewSize.y);
        }
        break;
    case Outer:
        if (ratioWidth < ratioHeight) {
            int newWidth = (int)(cameraPreviewSize.width*ratioHeight);
            int x = (hostViewSize.x - newWidth) / 2;
            toReturn = new Rect(x, 0, x+newWidth,hostViewSize.y);
        } else {
            int newHeight = (int)(cameraPreviewSize.height*ratioWidth);
            int y = (hostViewSize.y - newHeight) / 2;
            toReturn = new Rect(0, y, hostViewSize.x, y+newHeight);
        }
        break;
    }
    return toReturn;
}

private Camera.Size getNearestPreviewSize(Camera.Size size) {
  List<Camera.Size> availableSizes =  mCamera.getParameters().getSupportedPreviewSizes();
  if (availableSizes == null || availableSizes.size() <= 0) return null;

  Camera.Size toReturn = availableSizes.get(0);
  int distance = Math.abs(size.width*size.height - toReturn.width*toReturn.height);
  for (int a=1; a<availableSizes.size(); a++) {
      int temp = Math.abs(size.width*size.height - availableSizes.get(a).width*availableSizes.get(a).height);
      if (temp < distance) {
          distance = temp;
          toReturn = availableSizes.get(a);
      }
  }
  return toReturn;
 }


public int setCameraDisplayOrientation(int cameraId, android.hardware.Camera camera) {

     CameraInfo info = new Camera.CameraInfo();
     Camera.getCameraInfo(cameraId, info);
     int degrees = 0;

     switch (rotation) {
         case Surface.ROTATION_0: degrees = 0; break;
         case Surface.ROTATION_90: degrees = 90; break;
         case Surface.ROTATION_180: degrees = 180; break;
         case Surface.ROTATION_270: degrees = 270; break;
     }

     int result;
     if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
         result = (info.orientation + degrees) % 360;
         result = (360 - result) % 360;  // compensate the mirror
     } else {  // back-facing
         result = (info.orientation - degrees + 360) % 360;
     }
     camera.setDisplayOrientation(result);
     return result/90;
 }

}
CameraExtractionFragment.java

public class MainActivity extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.fragment_main);

    getFragmentManager().beginTransaction().add(R.id.mainLayout, new CameraExtractionFragment()).commit();
}
}
public class CameraExtractionFragment extends Fragment {

private CameraExtraction mCameraExtraction;
Camera mCamera;
int mNumberOfCameras;
int cameraId;
int rotation;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    mCameraExtraction = new CameraExtraction(
            this.getActivity().getBaseContext(), 
            this.getActivity().getWindowManager().getDefaultDisplay().getRotation()
            );

    // Find the total number of cameras available
    mNumberOfCameras = Camera.getNumberOfCameras();

    // Find the ID of the rear-facing ("default") camera
    CameraInfo cameraInfo = new CameraInfo();
    for (int i = 0; i < mNumberOfCameras; i++) {
        Camera.getCameraInfo(i, cameraInfo);
        if (cameraInfo.facing == CameraInfo.CAMERA_FACING_FRONT) {
            cameraId = i;
        }
    }
}

 @Override
 public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)               {
     return mCameraExtraction;
 }

 @Override
public void onResume() {
    super.onResume();

    // Use mCurrentCamera to select the camera desired to safely restore
    // the fragment after the camera has been changed
    mCamera = Camera.open(cameraId);
    mCameraExtraction.setCamera(mCamera);
}

@Override
public void onPause() {
    super.onPause();

    if (mCamera != null)
    {
        mCamera.release();
    }
}


// Modo en el que se pinta la cámara: encajada por dentro o saliendo los bordes por fuera.
public enum CameraViewMode {

    /**
     * Inner mode
     */
    Inner,
    /**
     * Outer mode 
     */
    Outer
}
}
public class CameraExtraction extends ViewGroup implements SurfaceHolder.Callback {

 private final String TAG = "CameraExtraction";

Camera mCamera;
SurfaceHolder mHolder;
SurfaceView mSurfaceView;
int mNumberOfCameras;
int cameraId;
Rect desiredSize;
CameraViewMode cameraViewMode;
boolean mSurfaceCreated = false;
List<Size> mSupportedPreviewSizes;
int rotation;
Size mPreviewSize;

public CameraExtraction(Context context, int rotation) {
    super(context);

    this.rotation = rotation;

    mSurfaceView = new SurfaceView(context);

    addView(mSurfaceView);

    // Install a SurfaceHolder.Callback so we get notified when the
    mHolder = mSurfaceView.getHolder();
    mHolder.addCallback(this);
    mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

    cameraViewMode = CameraViewMode.Inner;
}

public void setCamera(Camera camera) {
    mCamera = camera;
    if (mCamera != null) {
        mSupportedPreviewSizes = mCamera.getParameters().getSupportedPreviewSizes();
        if (mSurfaceCreated) requestLayout();
    }
}

public void switchCamera(Camera camera) {
    setCamera(camera);
    try {
        camera.setPreviewDisplay(mHolder);
    } catch (IOException exception) {
        Log.e(TAG, "IOException caused by setPreviewDisplay()", exception);
    }
}

@SuppressLint("DrawAllocation")
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    if (mSurfaceView == null ||mSurfaceView.getHolder() == null) return;

    if (mSurfaceView.getHolder().getSurface() == null) {
        // preview surface does not exist
        return;
    }

    final int width = resolveSize(getSuggestedMinimumWidth(),
            widthMeasureSpec);
    final int height = resolveSize(getSuggestedMinimumHeight(),
            heightMeasureSpec);
    setMeasuredDimension(width, height);

    if (mSupportedPreviewSizes != null) {

        mPreviewSize = getNearestPreviewSize(mCamera.new Size(widthMeasureSpec,heightMeasureSpec));
    }

    if (mCamera != null) {
      Camera.Parameters parameters = mCamera.getParameters();
      parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height);

      mCamera.setParameters(parameters);
    }
}

@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
    if (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.
        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);
        }
    }       
}

@Override
public void surfaceCreated(SurfaceHolder holder) {
    mCamera = Camera.open(cameraId);        
}

@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,int height) {
    if (mSurfaceView == null || mSurfaceView.getHolder() == null) return;

            if (mSurfaceView.getHolder().getSurface() == null) {
                // preview surface does not exist
                return;
            }

            // set preview size and make any resize, rotate or
            // reformatting changes here
            Camera.Parameters param = mCamera.getParameters();
            Point previewSize = new Point(640,480);

            Camera.Size size = getNearestPreviewSize(mCamera.new Size(previewSize.x,previewSize.y));
            param.setPreviewSize(size.width, size.height);
            mCamera.setParameters(param);
            rotation = setCameraDisplayOrientation(cameraId, mCamera);

            // start preview with new settings
            try {
                mCamera.setPreviewCallback(new Camera.PreviewCallback() {

                    @Override
                    public void onPreviewFrame(byte[] data, Camera camera) {
                        // TODO Auto-generated method stub

                    }
                });
                mCamera.setPreviewDisplay(mSurfaceView.getHolder());
                mCamera.startPreview();

            } catch (Exception e) {
                Log.d("AndroidControlSurfaceView",
                        "Error starting camera preview: " + e.getMessage());
            }       
}

@Override
public void surfaceDestroyed(SurfaceHolder holder) {
    if (mCamera != null)
    {
        mCamera.stopPreview();
        mCamera.release();
    }
}


protected Rect getCameraViewSizeCompensated(Camera.Size cameraPreviewSize, Point hostViewSize) {
    Rect toReturn=null;

    float ratioWidth = hostViewSize.x / (float)cameraPreviewSize.width;
    float ratioHeight = hostViewSize.y / (float)cameraPreviewSize.height;

    switch (cameraViewMode){
    case Inner:
        if (ratioWidth < ratioHeight) {
            int newHeight = (int)(cameraPreviewSize.height*ratioWidth);
            int y = (hostViewSize.y - newHeight) / 2;
            toReturn = new Rect(0, y, hostViewSize.x, y+newHeight);
        } else {
            int newWidth = (int)(cameraPreviewSize.width*ratioHeight);
            int x = (hostViewSize.x - newWidth) / 2;
            toReturn = new Rect(x, 0, x+newWidth,hostViewSize.y);
        }
        break;
    case Outer:
        if (ratioWidth < ratioHeight) {
            int newWidth = (int)(cameraPreviewSize.width*ratioHeight);
            int x = (hostViewSize.x - newWidth) / 2;
            toReturn = new Rect(x, 0, x+newWidth,hostViewSize.y);
        } else {
            int newHeight = (int)(cameraPreviewSize.height*ratioWidth);
            int y = (hostViewSize.y - newHeight) / 2;
            toReturn = new Rect(0, y, hostViewSize.x, y+newHeight);
        }
        break;
    }
    return toReturn;
}

private Camera.Size getNearestPreviewSize(Camera.Size size) {
  List<Camera.Size> availableSizes =  mCamera.getParameters().getSupportedPreviewSizes();
  if (availableSizes == null || availableSizes.size() <= 0) return null;

  Camera.Size toReturn = availableSizes.get(0);
  int distance = Math.abs(size.width*size.height - toReturn.width*toReturn.height);
  for (int a=1; a<availableSizes.size(); a++) {
      int temp = Math.abs(size.width*size.height - availableSizes.get(a).width*availableSizes.get(a).height);
      if (temp < distance) {
          distance = temp;
          toReturn = availableSizes.get(a);
      }
  }
  return toReturn;
 }


public int setCameraDisplayOrientation(int cameraId, android.hardware.Camera camera) {

     CameraInfo info = new Camera.CameraInfo();
     Camera.getCameraInfo(cameraId, info);
     int degrees = 0;

     switch (rotation) {
         case Surface.ROTATION_0: degrees = 0; break;
         case Surface.ROTATION_90: degrees = 90; break;
         case Surface.ROTATION_180: degrees = 180; break;
         case Surface.ROTATION_270: degrees = 270; break;
     }

     int result;
     if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
         result = (info.orientation + degrees) % 360;
         result = (360 - result) % 360;  // compensate the mirror
     } else {  // back-facing
         result = (info.orientation - degrees + 360) % 360;
     }
     camera.setDisplayOrientation(result);
     return result/90;
 }

}
公共类CameraExtractionFragment扩展了片段{
私人摄像机提取;
麦克默拉照相机;
国际货币基金组织;
int cameraId;
整数旋转;
@凌驾
创建时的公共void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
mCameraExtraction=新的CameraExtraction(
此.getActivity().getBaseContext(),
此.getActivity().getWindowManager().getDefaultDisplay().getRotation()文件
);
//查找可用相机的总数
mNumberOfCameras=Camera.getNumberOfCameras();
//查找后向(“默认”)摄像头的ID
camerRainfo camerRainfo=新的camerRainfo();
for(int i=0;i
CameraExtraction.java

public class MainActivity extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.fragment_main);

    getFragmentManager().beginTransaction().add(R.id.mainLayout, new CameraExtractionFragment()).commit();
}
}
public class CameraExtractionFragment extends Fragment {

private CameraExtraction mCameraExtraction;
Camera mCamera;
int mNumberOfCameras;
int cameraId;
int rotation;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    mCameraExtraction = new CameraExtraction(
            this.getActivity().getBaseContext(), 
            this.getActivity().getWindowManager().getDefaultDisplay().getRotation()
            );

    // Find the total number of cameras available
    mNumberOfCameras = Camera.getNumberOfCameras();

    // Find the ID of the rear-facing ("default") camera
    CameraInfo cameraInfo = new CameraInfo();
    for (int i = 0; i < mNumberOfCameras; i++) {
        Camera.getCameraInfo(i, cameraInfo);
        if (cameraInfo.facing == CameraInfo.CAMERA_FACING_FRONT) {
            cameraId = i;
        }
    }
}

 @Override
 public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)               {
     return mCameraExtraction;
 }

 @Override
public void onResume() {
    super.onResume();

    // Use mCurrentCamera to select the camera desired to safely restore
    // the fragment after the camera has been changed
    mCamera = Camera.open(cameraId);
    mCameraExtraction.setCamera(mCamera);
}

@Override
public void onPause() {
    super.onPause();

    if (mCamera != null)
    {
        mCamera.release();
    }
}


// Modo en el que se pinta la cámara: encajada por dentro o saliendo los bordes por fuera.
public enum CameraViewMode {

    /**
     * Inner mode
     */
    Inner,
    /**
     * Outer mode 
     */
    Outer
}
}
public class CameraExtraction extends ViewGroup implements SurfaceHolder.Callback {

 private final String TAG = "CameraExtraction";

Camera mCamera;
SurfaceHolder mHolder;
SurfaceView mSurfaceView;
int mNumberOfCameras;
int cameraId;
Rect desiredSize;
CameraViewMode cameraViewMode;
boolean mSurfaceCreated = false;
List<Size> mSupportedPreviewSizes;
int rotation;
Size mPreviewSize;

public CameraExtraction(Context context, int rotation) {
    super(context);

    this.rotation = rotation;

    mSurfaceView = new SurfaceView(context);

    addView(mSurfaceView);

    // Install a SurfaceHolder.Callback so we get notified when the
    mHolder = mSurfaceView.getHolder();
    mHolder.addCallback(this);
    mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

    cameraViewMode = CameraViewMode.Inner;
}

public void setCamera(Camera camera) {
    mCamera = camera;
    if (mCamera != null) {
        mSupportedPreviewSizes = mCamera.getParameters().getSupportedPreviewSizes();
        if (mSurfaceCreated) requestLayout();
    }
}

public void switchCamera(Camera camera) {
    setCamera(camera);
    try {
        camera.setPreviewDisplay(mHolder);
    } catch (IOException exception) {
        Log.e(TAG, "IOException caused by setPreviewDisplay()", exception);
    }
}

@SuppressLint("DrawAllocation")
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    if (mSurfaceView == null ||mSurfaceView.getHolder() == null) return;

    if (mSurfaceView.getHolder().getSurface() == null) {
        // preview surface does not exist
        return;
    }

    final int width = resolveSize(getSuggestedMinimumWidth(),
            widthMeasureSpec);
    final int height = resolveSize(getSuggestedMinimumHeight(),
            heightMeasureSpec);
    setMeasuredDimension(width, height);

    if (mSupportedPreviewSizes != null) {

        mPreviewSize = getNearestPreviewSize(mCamera.new Size(widthMeasureSpec,heightMeasureSpec));
    }

    if (mCamera != null) {
      Camera.Parameters parameters = mCamera.getParameters();
      parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height);

      mCamera.setParameters(parameters);
    }
}

@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
    if (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.
        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);
        }
    }       
}

@Override
public void surfaceCreated(SurfaceHolder holder) {
    mCamera = Camera.open(cameraId);        
}

@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,int height) {
    if (mSurfaceView == null || mSurfaceView.getHolder() == null) return;

            if (mSurfaceView.getHolder().getSurface() == null) {
                // preview surface does not exist
                return;
            }

            // set preview size and make any resize, rotate or
            // reformatting changes here
            Camera.Parameters param = mCamera.getParameters();
            Point previewSize = new Point(640,480);

            Camera.Size size = getNearestPreviewSize(mCamera.new Size(previewSize.x,previewSize.y));
            param.setPreviewSize(size.width, size.height);
            mCamera.setParameters(param);
            rotation = setCameraDisplayOrientation(cameraId, mCamera);

            // start preview with new settings
            try {
                mCamera.setPreviewCallback(new Camera.PreviewCallback() {

                    @Override
                    public void onPreviewFrame(byte[] data, Camera camera) {
                        // TODO Auto-generated method stub

                    }
                });
                mCamera.setPreviewDisplay(mSurfaceView.getHolder());
                mCamera.startPreview();

            } catch (Exception e) {
                Log.d("AndroidControlSurfaceView",
                        "Error starting camera preview: " + e.getMessage());
            }       
}

@Override
public void surfaceDestroyed(SurfaceHolder holder) {
    if (mCamera != null)
    {
        mCamera.stopPreview();
        mCamera.release();
    }
}


protected Rect getCameraViewSizeCompensated(Camera.Size cameraPreviewSize, Point hostViewSize) {
    Rect toReturn=null;

    float ratioWidth = hostViewSize.x / (float)cameraPreviewSize.width;
    float ratioHeight = hostViewSize.y / (float)cameraPreviewSize.height;

    switch (cameraViewMode){
    case Inner:
        if (ratioWidth < ratioHeight) {
            int newHeight = (int)(cameraPreviewSize.height*ratioWidth);
            int y = (hostViewSize.y - newHeight) / 2;
            toReturn = new Rect(0, y, hostViewSize.x, y+newHeight);
        } else {
            int newWidth = (int)(cameraPreviewSize.width*ratioHeight);
            int x = (hostViewSize.x - newWidth) / 2;
            toReturn = new Rect(x, 0, x+newWidth,hostViewSize.y);
        }
        break;
    case Outer:
        if (ratioWidth < ratioHeight) {
            int newWidth = (int)(cameraPreviewSize.width*ratioHeight);
            int x = (hostViewSize.x - newWidth) / 2;
            toReturn = new Rect(x, 0, x+newWidth,hostViewSize.y);
        } else {
            int newHeight = (int)(cameraPreviewSize.height*ratioWidth);
            int y = (hostViewSize.y - newHeight) / 2;
            toReturn = new Rect(0, y, hostViewSize.x, y+newHeight);
        }
        break;
    }
    return toReturn;
}

private Camera.Size getNearestPreviewSize(Camera.Size size) {
  List<Camera.Size> availableSizes =  mCamera.getParameters().getSupportedPreviewSizes();
  if (availableSizes == null || availableSizes.size() <= 0) return null;

  Camera.Size toReturn = availableSizes.get(0);
  int distance = Math.abs(size.width*size.height - toReturn.width*toReturn.height);
  for (int a=1; a<availableSizes.size(); a++) {
      int temp = Math.abs(size.width*size.height - availableSizes.get(a).width*availableSizes.get(a).height);
      if (temp < distance) {
          distance = temp;
          toReturn = availableSizes.get(a);
      }
  }
  return toReturn;
 }


public int setCameraDisplayOrientation(int cameraId, android.hardware.Camera camera) {

     CameraInfo info = new Camera.CameraInfo();
     Camera.getCameraInfo(cameraId, info);
     int degrees = 0;

     switch (rotation) {
         case Surface.ROTATION_0: degrees = 0; break;
         case Surface.ROTATION_90: degrees = 90; break;
         case Surface.ROTATION_180: degrees = 180; break;
         case Surface.ROTATION_270: degrees = 270; break;
     }

     int result;
     if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
         result = (info.orientation + degrees) % 360;
         result = (360 - result) % 360;  // compensate the mirror
     } else {  // back-facing
         result = (info.orientation - degrees + 360) % 360;
     }
     camera.setDisplayOrientation(result);
     return result/90;
 }

}
公共类CameraExtraction扩展了视图组,实现了SurfaceHolder.Callback{
私有最终字符串标记=“CameraExtraction”;
麦克默拉照相机;
表面粗糙度;
SurfaceView mSurfaceView;
国际货币基金组织;
int cameraId;
矩形所需尺寸;
CameraViewMode CameraViewMode;
布尔值mSurfaceCreated=false;
列出MSSupportedPreviewsizes;
整数旋转;
大小mPreviewSize;
公共摄影机提取(上下文、整数旋转){
超级(上下文);
这个旋转=旋转;
mSurfaceView=新的SurfaceView(上下文);
addView(mSurfaceView);
//安装SurfaceHolder.Callback,以便在
mHolder=mSurfaceView.getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE\u TYPE\u PUSH\u缓冲区);
cameraViewMode=cameraViewMode.internal;
}
公共摄像机(摄像机){
mCamera=摄像机;
if(mCamera!=null){
mSupportedPreviewSizes=mCamera.getParameters().getSupportedPreviewSizes();
如果(mSurfaceCreated)requestLayout();
}
}
公共摄像机(摄像机){
设置摄像机(摄像机);
试一试{
摄像头。设置预览显示(mHolder);
}捕获(IOException异常){
Log.e(标记“setPreviewDisplay()引起的IOException”,exception);
}
}
@SuppressLint(“DrawAllocation”)
@凌驾
测量时的保护空隙(内部宽度测量等级、内部高度测量等级){
if(mSurfaceView==null | | mSurfaceView.getHolder()==null)返回;
if(mSurfaceView.getHolder().getSurface()==null){
//预览曲面不存在
返回;
}
最终整数宽度=resolveSize(getSuggestedMinimumWidth(),
宽度(特殊);
最终整数高度=resolveSize(getSuggestedMinimumHeight(),
高度测量(特殊);
设置测量尺寸(宽度、高度);
if(mSupportedPreviewSizes!=null){
mPreviewSize=getNearestPreviewSize(mCamera.new Size(widthmasurespec,heightMeasureSpec));
}
if(mCamera!=null){
Camera.Parameters=mCamera.getParameters();
parameters.setPreviewSize(mPreviewSize.width、mPreviewSize.height);
mCamera.setParameters(参数);
}
}
@凌驾
仅受保护的void布局(布尔值已更改、int l、int t、int r、int b){
如果(getChildCount()>0){
最终视图子对象=getChildAt(0);
最终整数宽度=r-l;
最终内部高度=b-t;
int previewWidth=宽度;
亮度=高度;
if(mPreviewSize!=null){
previewWidth=mPreviewSize.width;
PreviewView=mPreviewSize.height;
}
//将子曲面视图居中放置在父曲面视图中。
如果(宽度*预览宽度>高度*预览宽度){
最终整数scaledChildWidth=预览宽度*高度
/预演;
布局((宽度-scaledChildWidth)/2,0,
(宽度+缩放儿童宽度)/2,高度);
}否则{
最终int scaledChildHeight=预览视图*宽度
/预览宽度;
布局(0,(高度-缩放儿童高度)/2,宽度,
(身高+缩放儿童身高)/2);
}
}       
}
@凌驾
已创建的公共空白表面(表面持有人){
mCamera=Camera.open(cameraId);
}
@凌驾
公共空白表面更改(表面文件夹持有者、整型格式、整型宽度、整型高度){
if(mSurfaceView==null | | mSurfaceView.getHolder()==null)返回;
if(mSurfaceView.getHolder().getSurface()==null){
//预览曲面不存在
返回;
}
//设置预览大小并进行任何调整大小、旋转或
//在此处重新格式化更改
Camera.Parameters param=mCamera.getParameters();
点预览大小=新点(640480);
Camera.Size Size=getNearestPreviewSize(mCamera.new Size)(previewSize.x,previ