我想获得全屏人像相机预览.使用Google的示例,预览在纵向屏幕上以横向格式进行.当我将预览设置为480 x 864(与工作景观尺寸相反)时,出现setParameters Failed错误.
我已经阅读了所有可以找到的StackOverflow,但是我无法弄清楚为什么横向支持的尺寸无法通过纵向显示.我也找不到强迫全屏人像预览的方法.手机上的“相机”应用可提供全屏人像预览,因此我知道这不是硬件限制.
我正在使用运行Android 2.3.3的DroID 3进行测试
我将不胜感激任何建议.
public class SimplePrevIEw extends VIEwGroup implements SurfaceHolder.Callback {private final String TAG = "PrevIEw";SurfaceVIEw mSurfaceVIEw;SurfaceHolder mHolder;Size mPrevIEwSize;List<Size> mSupportedPrevIEwSizes;Camera mCamera;int cameraID;Activity activity;public SimplePrevIEw(Activity context, int defaultCamera) { super(context); activity = context; cameraID = defaultCamera; 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(); }}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);}@OverrIDeprotected 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); Log.i(TAG, "setting VIEw measured dimensions to wIDth: " + wIDth + " height: " + height); setMeasuredDimension(wIDth, height); if (mSupportedPrevIEwSizes != null) { mPrevIEwSize = getoptimalPrevIEwSize(mSupportedPrevIEwSizes, wIDth, height); }}@OverrIDeprotected 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. 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 surfaceDestroyed(SurfaceHolder holder) { // Surface will be destroyed when we return, so stop the prevIEw. if (mCamera != null) { mCamera.stopPrevIEw(); }}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) { Log.v(TAG, " wIDth: " + size.wIDth + " height: " + size.height); 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); } } } Log.i(TAG, "optimal prevIEw wIDth: " + optimalSize.wIDth + " height: " + optimalSize.height); return optimalSize;}public voID surfaceCreated(SurfaceHolder holder) { // The Surface has been created, acquire the camera and tell it where // to draw. try { if (mCamera != null) { final int wIDth = getWIDth(); final int height = getHeight(); Log.i(TAG, "vIEw wIDth: " + wIDth + " height: " + height); if (height > wIDth) { Log.i(TAG, "in portrait mode so rotate camera prevIEw"); // THis line fixed the camera display orIEntation. seems to // have to be called before setPrevIEwdisplay() mCamera.setdisplayOrIEntation(90); } mCamera.setPrevIEwdisplay(holder); } } catch (IOException exception) { Log.e(TAG, "IOException caused by setPrevIEwdisplay()", exception); }}/** * orIEntation and rotation work done here. Now that the size is kNown, set * up the camera parameters and begin the prevIEw. */public voID surfaceChanged(SurfaceHolder holder, int format, int w, int h) { if (mCamera != null) { mCamera.stopPrevIEw(); Camera.Parameters parameters = mCamera.getParameters(); // mCamera.setdisplayOrIEntation(90); final int wIDth = getWIDth(); final int height = getHeight(); Log.i(TAG, "vIEw wIDth: " + wIDth + " height: " + height); if (height > wIDth) { Log.i(TAG, "portrait: setting prevIEw wIDth: " + 480 + " height: " + 864); parameters.setPrevIEwSize(480, 864); // had no effect parameters.set("orIEntation", "portrait"); } else { Log.i(TAG, "landscape: setting prevIEw wIDth: " + mPrevIEwSize.wIDth + " height: " + mPrevIEwSize.height); parameters.setPrevIEwSize(mPrevIEwSize.wIDth, mPrevIEwSize.height); } requestLayout(); // *** following line throws setParameters Failed error *** mCamera.setParameters(parameters); mCamera.startPrevIEw(); }}}
以及来自Activity的onCreate()的调用:
prevIEw = new SimplePrevIEw(this, defaultCameraID); setContentVIEw(prevIEw);
解决方法:
试试这个代码:
package com.example.dragme;import java.io.IOException;import java.util.List;import androID.app.Activity;import androID.content.Context;import androID.content.res.Configuration;import androID.harDWare.Camera;import androID.os.Build;import androID.util.Log;import androID.vIEw.display;import androID.vIEw.Surface;import androID.vIEw.SurfaceHolder;import androID.vIEw.SurfaceVIEw;public class CameraPrevIEw extends SurfaceVIEw implements SurfaceHolder.Callback { private SurfaceHolder mHolder; public Camera mCamera; 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; protected List<Camera.Size> mPrevIEwSizeList; protected List<Camera.Size> mPictureSizeList; protected Camera.Size mPrevIEwSize; protected Camera.Size mPictureSize; public CameraPrevIEw(Context context, Camera camera) { super(context); mActivity=(Activity)context; mCamera = camera; // Install a SurfaceHolder.Callback so we get notifIEd when the // underlying surface is created and destroyed. mHolder = getHolder(); mHolder.addCallback(this); // deprecated setting, but required on AndroID versions prior to 3.0 mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); } public voID surfaceCreated(SurfaceHolder holder) { // The Surface has been created, Now tell the camera where to draw the prevIEw. try { mCamera.setPrevIEwdisplay(holder); mCamera.startPrevIEw(); } catch (IOException e) { Log.d("Cameraview", "Error setting camera prevIEw: " + e.getMessage()); } } public voID surfaceDestroyed(SurfaceHolder holder) { // empty. Take care of releasing the Camera prevIEw in your activity. } public voID surfaceChanged(SurfaceHolder holder, int format, int w, int h) { // If your prevIEw can change or rotate, take care of those events here. // Make sure to stop the prevIEw before resizing or reformatting it. if (mHolder.getSurface() == null){ // prevIEw surface does not exist return; } // stop prevIEw before making changes try { // mCamera.stopPrevIEw(); } catch (Exception e){ // ignore: trIEd to stop a non-existent prevIEw } // set prevIEw size and make any resize, rotate or // reformatting changes here // start prevIEw with new settings try { Camera.Parameters cameraParams = mCamera.getParameters(); boolean portrait = isPortrait(); configureCameraParameters(cameraParams, portrait); mCamera.setPrevIEwdisplay(mHolder); mCamera.startPrevIEw(); } catch (Exception e){ Log.d("Cameraview", "Error starting camera prevIEw: " + e.getMessage()); } } public voID onPause() { if (null == mCamera) { return; } mCamera.stopPrevIEw(); mCamera.release(); mCamera = null; } 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); } 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); } mCamera.setParameters(cameraParams); } public boolean isPortrait() { return (mActivity.getResources().getConfiguration().orIEntation == Configuration.ORIENTATION_PORTRAIT); }}
总结 以上是内存溢出为你收集整理的相机预览肖像setParameters失败全部内容,希望文章能够帮你解决相机预览肖像setParameters失败所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)