自定义相机预览拉伸
Custom camera preview stretched
我创建了自定义相机(水平模式下必须)来捕捉图像。
但是我在一些设备上遇到了问题,比如 motorola g3 和 g4,它在三星设备上运行得很好。
可以帮忙解决这个问题。
使用属性android:adjustViewBounds="true"
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:adjustViewBounds="true"
android:visibility="gone" />
我通过创建不带 xml、
的自定义 activity 文件解决了上述问题
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Requires RelativeLayout.
mLayout = new RelativeLayout(this);
setContentView(mLayout);
}
@Override
protected void onResume() {
super.onResume();
//Outter layout
// Set the second argument by your choice.
// Usually, 0 for back-facing camera, 1 for front-facing camera.
// If the OS is pre-gingerbreak, this does not have any effect.
mPreview = new CameraPreview(this, 0, CameraPreview.LayoutMode.FitToParent);
RelativeLayout.LayoutParams previewLayoutParams = new RelativeLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
mLayout.addView(mPreview, 0, previewLayoutParams);
//Capture button
captureButton = new Button(this);
RelativeLayout.LayoutParams bParams = new RelativeLayout.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
bParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, RelativeLayout.TRUE);
bParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT, RelativeLayout.TRUE);
captureButton.setText("Capture");
mLayout.addView(captureButton, bParams);
captureButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mPreview.takePhoto();
}
});
}
现在创建 CameraPreview class
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
private static boolean DEBUGGING = true;
private static final String LOG_TAG = "CameraPreviewSample";
private static final String CAMERA_PARAM_ORIENTATION = "orientation";
private static final String CAMERA_PARAM_LANDSCAPE = "landscape";
private static final String CAMERA_PARAM_PORTRAIT = "portrait";
protected Activity mActivity;
private SurfaceHolder mHolder;
protected Camera mCamera;
protected List<Camera.Size> mPreviewSizeList;
protected List<Camera.Size> mPictureSizeList;
protected Camera.Size mPreviewSize;
protected Camera.Size mPictureSize;
private int mSurfaceChangedCallDepth = 0;
private int mCameraId;
private LayoutMode mLayoutMode;
private int mCenterPosX = -1;
private int mCenterPosY;
private CameraApp cameraApp;
private ImageCallback imageCallback;
private List<Camera.Size> mSupportedPreviewSizes;
PreviewReadyCallback mPreviewReadyCallback = null;
public static enum LayoutMode {
FitToParent, // Scale to the size that no side is larger than the parent
NoBlank // Scale to the size that no side is smaller than the parent
};
public interface PreviewReadyCallback {
public void onPreviewReady();
}
/**
* State flag: true when surface's layout size is set and surfaceChanged()
* process has not been completed.
*/
protected boolean mSurfaceConfiguring = false;
public CameraPreview(Activity activity, int cameraId, LayoutMode mode) {
super(activity); // Always necessary
mActivity = activity;
mLayoutMode = mode;
mHolder = getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) {
if (Camera.getNumberOfCameras() > cameraId) {
mCameraId = cameraId;
} else {
mCameraId = 0;
}
} else {
mCameraId = 0;
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) {
mCamera = Camera.open(mCameraId);
} else {
mCamera = Camera.open();
}
mSupportedPreviewSizes = mCamera.getParameters().getSupportedPreviewSizes();
Camera.Parameters cameraParams = mCamera.getParameters();
mPreviewSizeList = cameraParams.getSupportedPreviewSizes();
mPictureSizeList = cameraParams.getSupportedPictureSizes();
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
try {
mCamera.setPreviewDisplay(mHolder);
} catch (IOException e) {
mCamera.release();
mCamera = null;
}
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
mSurfaceChangedCallDepth++;
doSurfaceChanged(width, height);
mSurfaceChangedCallDepth--;
}
private void doSurfaceChanged(int width, int height) {
mCamera.stopPreview();
Camera.Parameters cameraParams = mCamera.getParameters();
boolean portrait = isPortrait();
// The code in this if-statement is prevented from executed again when surfaceChanged is
// called again due to the change of the layout size in this if-statement.
if (!mSurfaceConfiguring) {
Camera.Size previewSize = determinePreviewSize(portrait, width, height);
Camera.Size pictureSize = determinePictureSize(previewSize);
if (DEBUGGING) { Log.v(LOG_TAG, "Desired Preview Size - w: " + width + ", h: " + height); }
mPreviewSize = previewSize;
mPictureSize = pictureSize;
mSurfaceConfiguring = adjustSurfaceLayoutSize(previewSize, portrait, width, height);
// Continue executing this method if this method is called recursively.
// Recursive call of surfaceChanged is very special case, which is a path from
// the catch clause at the end of this method.
// The later part of this method should be executed as well in the recursive
// invocation of this method, because the layout change made in this recursive
// call will not trigger another invocation of this method.
if (mSurfaceConfiguring && (mSurfaceChangedCallDepth <= 1)) {
return;
}
}
configureCameraParameters(cameraParams, portrait);
mSurfaceConfiguring = false;
try {
mCamera.startPreview();
} catch (Exception e) {
Log.w(LOG_TAG, "Failed to start preview: " + e.getMessage());
// Remove failed size
mPreviewSizeList.remove(mPreviewSize);
mPreviewSize = null;
// Reconfigure
if (mPreviewSizeList.size() > 0) { // prevent infinite loop
surfaceChanged(null, 0, width, height);
} else {
Toast.makeText(mActivity, "Can't start preview", Toast.LENGTH_LONG).show();
Log.w(LOG_TAG, "Gave up starting preview");
}
}
if (null != mPreviewReadyCallback) {
mPreviewReadyCallback.onPreviewReady();
}
}
/**
* @param portrait
* @param reqWidth must be the value of the parameter passed in surfaceChanged
* @param reqHeight must be the value of the parameter passed in surfaceChanged
* @return Camera.Size object that is an element of the list returned from Camera.Parameters.getSupportedPreviewSizes.
*/
protected Camera.Size determinePreviewSize(boolean portrait, int reqWidth, int reqHeight) {
// Meaning of width and height is switched for preview when portrait,
// while it is the same as user's view for surface and metrics.
// That is, width must always be larger than height for setPreviewSize.
int reqPreviewWidth; // requested width in terms of camera hardware
int reqPreviewHeight; // requested height in terms of camera hardware
if (portrait) {
reqPreviewWidth = reqHeight;
reqPreviewHeight = reqWidth;
} else {
reqPreviewWidth = reqWidth;
reqPreviewHeight = reqHeight;
}
if (DEBUGGING) {
Log.v(LOG_TAG, "Listing all supported preview sizes");
for (Camera.Size size : mPreviewSizeList) {
Log.v(LOG_TAG, " w: " + size.width + ", h: " + size.height);
}
Log.v(LOG_TAG, "Listing all supported picture sizes");
for (Camera.Size size : mPictureSizeList) {
Log.v(LOG_TAG, " w: " + size.width + ", h: " + size.height);
}
}
// Adjust surface size with the closest aspect-ratio
float reqRatio = ((float) reqPreviewWidth) / reqPreviewHeight;
float curRatio, deltaRatio;
float deltaRatioMin = Float.MAX_VALUE;
Camera.Size retSize = null;
for (Camera.Size size : mPreviewSizeList) {
curRatio = ((float) size.width) / size.height;
deltaRatio = Math.abs(reqRatio - curRatio);
if (deltaRatio < deltaRatioMin) {
deltaRatioMin = deltaRatio;
retSize = size;
}
}
return retSize;
}
protected Camera.Size determinePictureSize(Camera.Size previewSize) {
Camera.Size retSize = null;
for (Camera.Size size : mPictureSizeList) {
if (size.equals(previewSize)) {
return size;
}
}
if (DEBUGGING) { Log.v(LOG_TAG, "Same picture size not found."); }
// if the preview size is not supported as a picture size
float reqRatio = ((float) previewSize.width) / previewSize.height;
float curRatio, deltaRatio;
float deltaRatioMin = Float.MAX_VALUE;
for (Camera.Size size : mPictureSizeList) {
curRatio = ((float) size.width) / size.height;
deltaRatio = Math.abs(reqRatio - curRatio);
if (deltaRatio < deltaRatioMin) {
deltaRatioMin = deltaRatio;
retSize = size;
}
}
return retSize;
}
protected boolean adjustSurfaceLayoutSize(Camera.Size previewSize, boolean portrait,
int availableWidth, int availableHeight) {
float tmpLayoutHeight, tmpLayoutWidth;
if (portrait) {
tmpLayoutHeight = previewSize.width;
tmpLayoutWidth = previewSize.height;
} else {
tmpLayoutHeight = previewSize.height;
tmpLayoutWidth = previewSize.width;
}
float factH, factW, fact;
factH = availableHeight / tmpLayoutHeight;
factW = availableWidth / tmpLayoutWidth;
if (mLayoutMode == LayoutMode.FitToParent) {
// Select smaller factor, because the surface cannot be set to the size larger than display metrics.
if (factH < factW) {
fact = factH;
} else {
fact = factW;
}
} else {
if (factH < factW) {
fact = factW;
} else {
fact = factH;
}
}
RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams)this.getLayoutParams();
int layoutHeight = (int) (tmpLayoutHeight * fact);
int layoutWidth = (int) (tmpLayoutWidth * fact);
if (DEBUGGING) {
Log.v(LOG_TAG, "Preview Layout Size - w: " + layoutWidth + ", h: " + layoutHeight);
Log.v(LOG_TAG, "Scale factor: " + fact);
}
boolean layoutChanged;
if ((layoutWidth != this.getWidth()) || (layoutHeight != this.getHeight())) {
layoutParams.height = layoutHeight;
layoutParams.width = layoutWidth;
if (mCenterPosX >= 0) {
layoutParams.topMargin = mCenterPosY - (layoutHeight / 2);
layoutParams.leftMargin = mCenterPosX - (layoutWidth / 2);
}
this.setLayoutParams(layoutParams); // this will trigger another surfaceChanged invocation.
layoutChanged = true;
} else {
layoutChanged = false;
}
return layoutChanged;
}
/**
* @param x X coordinate of center position on the screen. Set to negative value to unset.
* @param y Y coordinate of center position on the screen.
*/
public void setCenterPosition(int x, int y) {
mCenterPosX = x;
mCenterPosY = y;
}
protected void configureCameraParameters(Camera.Parameters cameraParams, boolean portrait) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.FROYO) { // for 2.1 and before
if (portrait) {
//cameraParams.set(CAMERA_PARAM_ORIENTATION, CAMERA_PARAM_PORTRAIT);
cameraParams.set(CAMERA_PARAM_ORIENTATION, CAMERA_PARAM_LANDSCAPE);
} else {
cameraParams.set(CAMERA_PARAM_ORIENTATION, CAMERA_PARAM_LANDSCAPE);
}
} else { // for 2.2 and later
int angle;
Display display = mActivity.getWindowManager().getDefaultDisplay();
switch (display.getRotation()) {
case Surface.ROTATION_0: // This is display orientation
angle = 90; // This is camera orientation
break;
case Surface.ROTATION_90:
angle = 0;
break;
case Surface.ROTATION_180:
angle = 270;
break;
case Surface.ROTATION_270:
angle = 180;
break;
default:
angle = 90;
break;
}
Log.v(LOG_TAG, "angle: " + angle);
mCamera.setDisplayOrientation(angle);
}
cameraParams.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
cameraParams.setPictureSize(mPictureSize.width, mPictureSize.height);
if (DEBUGGING) {
Log.v(LOG_TAG, "Preview Actual Size - w: " + mPreviewSize.width + ", h: " + mPreviewSize.height);
Log.v(LOG_TAG, "Picture Actual Size - w: " + mPictureSize.width + ", h: " + mPictureSize.height);
}
if (cameraParams.getSupportedFocusModes().contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO)) {
cameraParams.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);
}
mCamera.setParameters(cameraParams);
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
stop();
}
public void stop() {
if (null == mCamera) {
return;
}
mCamera.stopPreview();
mCamera.release();
mCamera = null;
}
public boolean isPortrait() {
return (mActivity.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT);
}
public void setOneShotPreviewCallback(PreviewCallback callback) {
if (null == mCamera) {
return;
}
mCamera.setOneShotPreviewCallback(callback);
}
public void setPreviewCallback(PreviewCallback callback) {
if (null == mCamera) {
return;
}
mCamera.setPreviewCallback(callback);
}
public Camera.Size getPreviewSize() {
return mPreviewSize;
}
public void setOnPreviewReady(PreviewReadyCallback cb) {
mPreviewReadyCallback = cb;
}
public void takePhoto(){
if(mCamera != null){
mCamera.takePicture(null, null, new Camera.PictureCallback() {
@Override
public void onPictureTaken(byte[] bytes, Camera camera) {
if(bytes.length > 0){
Log.d("CameraPreview","Yes!!! We got an Image");
}
Bitmap capturedBitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
//capturedBitmap = Bitmap.createScaledBitmap(capturedBitmap,1196,527,true);
imageCallback = (ImageCallback) mActivity;
imageCallback.resultImage(capturedBitmap);
}
});
}
}
就是这样!!,你快完成了
您还需要创建的另一件事是在主 activity 中获取结果的界面。
请。随时询问您的问题。
我创建了自定义相机(水平模式下必须)来捕捉图像。 但是我在一些设备上遇到了问题,比如 motorola g3 和 g4,它在三星设备上运行得很好。
可以帮忙解决这个问题。
使用属性android:adjustViewBounds="true"
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:adjustViewBounds="true"
android:visibility="gone" />
我通过创建不带 xml、
的自定义 activity 文件解决了上述问题@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Requires RelativeLayout.
mLayout = new RelativeLayout(this);
setContentView(mLayout);
}
@Override
protected void onResume() {
super.onResume();
//Outter layout
// Set the second argument by your choice.
// Usually, 0 for back-facing camera, 1 for front-facing camera.
// If the OS is pre-gingerbreak, this does not have any effect.
mPreview = new CameraPreview(this, 0, CameraPreview.LayoutMode.FitToParent);
RelativeLayout.LayoutParams previewLayoutParams = new RelativeLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
mLayout.addView(mPreview, 0, previewLayoutParams);
//Capture button
captureButton = new Button(this);
RelativeLayout.LayoutParams bParams = new RelativeLayout.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
bParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, RelativeLayout.TRUE);
bParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT, RelativeLayout.TRUE);
captureButton.setText("Capture");
mLayout.addView(captureButton, bParams);
captureButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mPreview.takePhoto();
}
});
}
现在创建 CameraPreview class
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
private static boolean DEBUGGING = true;
private static final String LOG_TAG = "CameraPreviewSample";
private static final String CAMERA_PARAM_ORIENTATION = "orientation";
private static final String CAMERA_PARAM_LANDSCAPE = "landscape";
private static final String CAMERA_PARAM_PORTRAIT = "portrait";
protected Activity mActivity;
private SurfaceHolder mHolder;
protected Camera mCamera;
protected List<Camera.Size> mPreviewSizeList;
protected List<Camera.Size> mPictureSizeList;
protected Camera.Size mPreviewSize;
protected Camera.Size mPictureSize;
private int mSurfaceChangedCallDepth = 0;
private int mCameraId;
private LayoutMode mLayoutMode;
private int mCenterPosX = -1;
private int mCenterPosY;
private CameraApp cameraApp;
private ImageCallback imageCallback;
private List<Camera.Size> mSupportedPreviewSizes;
PreviewReadyCallback mPreviewReadyCallback = null;
public static enum LayoutMode {
FitToParent, // Scale to the size that no side is larger than the parent
NoBlank // Scale to the size that no side is smaller than the parent
};
public interface PreviewReadyCallback {
public void onPreviewReady();
}
/**
* State flag: true when surface's layout size is set and surfaceChanged()
* process has not been completed.
*/
protected boolean mSurfaceConfiguring = false;
public CameraPreview(Activity activity, int cameraId, LayoutMode mode) {
super(activity); // Always necessary
mActivity = activity;
mLayoutMode = mode;
mHolder = getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) {
if (Camera.getNumberOfCameras() > cameraId) {
mCameraId = cameraId;
} else {
mCameraId = 0;
}
} else {
mCameraId = 0;
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) {
mCamera = Camera.open(mCameraId);
} else {
mCamera = Camera.open();
}
mSupportedPreviewSizes = mCamera.getParameters().getSupportedPreviewSizes();
Camera.Parameters cameraParams = mCamera.getParameters();
mPreviewSizeList = cameraParams.getSupportedPreviewSizes();
mPictureSizeList = cameraParams.getSupportedPictureSizes();
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
try {
mCamera.setPreviewDisplay(mHolder);
} catch (IOException e) {
mCamera.release();
mCamera = null;
}
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
mSurfaceChangedCallDepth++;
doSurfaceChanged(width, height);
mSurfaceChangedCallDepth--;
}
private void doSurfaceChanged(int width, int height) {
mCamera.stopPreview();
Camera.Parameters cameraParams = mCamera.getParameters();
boolean portrait = isPortrait();
// The code in this if-statement is prevented from executed again when surfaceChanged is
// called again due to the change of the layout size in this if-statement.
if (!mSurfaceConfiguring) {
Camera.Size previewSize = determinePreviewSize(portrait, width, height);
Camera.Size pictureSize = determinePictureSize(previewSize);
if (DEBUGGING) { Log.v(LOG_TAG, "Desired Preview Size - w: " + width + ", h: " + height); }
mPreviewSize = previewSize;
mPictureSize = pictureSize;
mSurfaceConfiguring = adjustSurfaceLayoutSize(previewSize, portrait, width, height);
// Continue executing this method if this method is called recursively.
// Recursive call of surfaceChanged is very special case, which is a path from
// the catch clause at the end of this method.
// The later part of this method should be executed as well in the recursive
// invocation of this method, because the layout change made in this recursive
// call will not trigger another invocation of this method.
if (mSurfaceConfiguring && (mSurfaceChangedCallDepth <= 1)) {
return;
}
}
configureCameraParameters(cameraParams, portrait);
mSurfaceConfiguring = false;
try {
mCamera.startPreview();
} catch (Exception e) {
Log.w(LOG_TAG, "Failed to start preview: " + e.getMessage());
// Remove failed size
mPreviewSizeList.remove(mPreviewSize);
mPreviewSize = null;
// Reconfigure
if (mPreviewSizeList.size() > 0) { // prevent infinite loop
surfaceChanged(null, 0, width, height);
} else {
Toast.makeText(mActivity, "Can't start preview", Toast.LENGTH_LONG).show();
Log.w(LOG_TAG, "Gave up starting preview");
}
}
if (null != mPreviewReadyCallback) {
mPreviewReadyCallback.onPreviewReady();
}
}
/**
* @param portrait
* @param reqWidth must be the value of the parameter passed in surfaceChanged
* @param reqHeight must be the value of the parameter passed in surfaceChanged
* @return Camera.Size object that is an element of the list returned from Camera.Parameters.getSupportedPreviewSizes.
*/
protected Camera.Size determinePreviewSize(boolean portrait, int reqWidth, int reqHeight) {
// Meaning of width and height is switched for preview when portrait,
// while it is the same as user's view for surface and metrics.
// That is, width must always be larger than height for setPreviewSize.
int reqPreviewWidth; // requested width in terms of camera hardware
int reqPreviewHeight; // requested height in terms of camera hardware
if (portrait) {
reqPreviewWidth = reqHeight;
reqPreviewHeight = reqWidth;
} else {
reqPreviewWidth = reqWidth;
reqPreviewHeight = reqHeight;
}
if (DEBUGGING) {
Log.v(LOG_TAG, "Listing all supported preview sizes");
for (Camera.Size size : mPreviewSizeList) {
Log.v(LOG_TAG, " w: " + size.width + ", h: " + size.height);
}
Log.v(LOG_TAG, "Listing all supported picture sizes");
for (Camera.Size size : mPictureSizeList) {
Log.v(LOG_TAG, " w: " + size.width + ", h: " + size.height);
}
}
// Adjust surface size with the closest aspect-ratio
float reqRatio = ((float) reqPreviewWidth) / reqPreviewHeight;
float curRatio, deltaRatio;
float deltaRatioMin = Float.MAX_VALUE;
Camera.Size retSize = null;
for (Camera.Size size : mPreviewSizeList) {
curRatio = ((float) size.width) / size.height;
deltaRatio = Math.abs(reqRatio - curRatio);
if (deltaRatio < deltaRatioMin) {
deltaRatioMin = deltaRatio;
retSize = size;
}
}
return retSize;
}
protected Camera.Size determinePictureSize(Camera.Size previewSize) {
Camera.Size retSize = null;
for (Camera.Size size : mPictureSizeList) {
if (size.equals(previewSize)) {
return size;
}
}
if (DEBUGGING) { Log.v(LOG_TAG, "Same picture size not found."); }
// if the preview size is not supported as a picture size
float reqRatio = ((float) previewSize.width) / previewSize.height;
float curRatio, deltaRatio;
float deltaRatioMin = Float.MAX_VALUE;
for (Camera.Size size : mPictureSizeList) {
curRatio = ((float) size.width) / size.height;
deltaRatio = Math.abs(reqRatio - curRatio);
if (deltaRatio < deltaRatioMin) {
deltaRatioMin = deltaRatio;
retSize = size;
}
}
return retSize;
}
protected boolean adjustSurfaceLayoutSize(Camera.Size previewSize, boolean portrait,
int availableWidth, int availableHeight) {
float tmpLayoutHeight, tmpLayoutWidth;
if (portrait) {
tmpLayoutHeight = previewSize.width;
tmpLayoutWidth = previewSize.height;
} else {
tmpLayoutHeight = previewSize.height;
tmpLayoutWidth = previewSize.width;
}
float factH, factW, fact;
factH = availableHeight / tmpLayoutHeight;
factW = availableWidth / tmpLayoutWidth;
if (mLayoutMode == LayoutMode.FitToParent) {
// Select smaller factor, because the surface cannot be set to the size larger than display metrics.
if (factH < factW) {
fact = factH;
} else {
fact = factW;
}
} else {
if (factH < factW) {
fact = factW;
} else {
fact = factH;
}
}
RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams)this.getLayoutParams();
int layoutHeight = (int) (tmpLayoutHeight * fact);
int layoutWidth = (int) (tmpLayoutWidth * fact);
if (DEBUGGING) {
Log.v(LOG_TAG, "Preview Layout Size - w: " + layoutWidth + ", h: " + layoutHeight);
Log.v(LOG_TAG, "Scale factor: " + fact);
}
boolean layoutChanged;
if ((layoutWidth != this.getWidth()) || (layoutHeight != this.getHeight())) {
layoutParams.height = layoutHeight;
layoutParams.width = layoutWidth;
if (mCenterPosX >= 0) {
layoutParams.topMargin = mCenterPosY - (layoutHeight / 2);
layoutParams.leftMargin = mCenterPosX - (layoutWidth / 2);
}
this.setLayoutParams(layoutParams); // this will trigger another surfaceChanged invocation.
layoutChanged = true;
} else {
layoutChanged = false;
}
return layoutChanged;
}
/**
* @param x X coordinate of center position on the screen. Set to negative value to unset.
* @param y Y coordinate of center position on the screen.
*/
public void setCenterPosition(int x, int y) {
mCenterPosX = x;
mCenterPosY = y;
}
protected void configureCameraParameters(Camera.Parameters cameraParams, boolean portrait) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.FROYO) { // for 2.1 and before
if (portrait) {
//cameraParams.set(CAMERA_PARAM_ORIENTATION, CAMERA_PARAM_PORTRAIT);
cameraParams.set(CAMERA_PARAM_ORIENTATION, CAMERA_PARAM_LANDSCAPE);
} else {
cameraParams.set(CAMERA_PARAM_ORIENTATION, CAMERA_PARAM_LANDSCAPE);
}
} else { // for 2.2 and later
int angle;
Display display = mActivity.getWindowManager().getDefaultDisplay();
switch (display.getRotation()) {
case Surface.ROTATION_0: // This is display orientation
angle = 90; // This is camera orientation
break;
case Surface.ROTATION_90:
angle = 0;
break;
case Surface.ROTATION_180:
angle = 270;
break;
case Surface.ROTATION_270:
angle = 180;
break;
default:
angle = 90;
break;
}
Log.v(LOG_TAG, "angle: " + angle);
mCamera.setDisplayOrientation(angle);
}
cameraParams.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
cameraParams.setPictureSize(mPictureSize.width, mPictureSize.height);
if (DEBUGGING) {
Log.v(LOG_TAG, "Preview Actual Size - w: " + mPreviewSize.width + ", h: " + mPreviewSize.height);
Log.v(LOG_TAG, "Picture Actual Size - w: " + mPictureSize.width + ", h: " + mPictureSize.height);
}
if (cameraParams.getSupportedFocusModes().contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO)) {
cameraParams.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);
}
mCamera.setParameters(cameraParams);
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
stop();
}
public void stop() {
if (null == mCamera) {
return;
}
mCamera.stopPreview();
mCamera.release();
mCamera = null;
}
public boolean isPortrait() {
return (mActivity.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT);
}
public void setOneShotPreviewCallback(PreviewCallback callback) {
if (null == mCamera) {
return;
}
mCamera.setOneShotPreviewCallback(callback);
}
public void setPreviewCallback(PreviewCallback callback) {
if (null == mCamera) {
return;
}
mCamera.setPreviewCallback(callback);
}
public Camera.Size getPreviewSize() {
return mPreviewSize;
}
public void setOnPreviewReady(PreviewReadyCallback cb) {
mPreviewReadyCallback = cb;
}
public void takePhoto(){
if(mCamera != null){
mCamera.takePicture(null, null, new Camera.PictureCallback() {
@Override
public void onPictureTaken(byte[] bytes, Camera camera) {
if(bytes.length > 0){
Log.d("CameraPreview","Yes!!! We got an Image");
}
Bitmap capturedBitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
//capturedBitmap = Bitmap.createScaledBitmap(capturedBitmap,1196,527,true);
imageCallback = (ImageCallback) mActivity;
imageCallback.resultImage(capturedBitmap);
}
});
}
}
就是这样!!,你快完成了 您还需要创建的另一件事是在主 activity 中获取结果的界面。 请。随时询问您的问题。