Quiero establecer la orientación de la cámara según la orientación del dispositivo en Android, pero nada parece funcionar. Traté de girar la Superficie así como los parámetros de la cámara, pero la vista previa de la cámara en el modo de retrato siempre viene al revés. Yo tendría que girar 90 grados hacia la derecha para que sea correcta. Aquí es el código que estoy usando ahora, que funciona en modo horizontal solamente.

    SurfaceHolder.Callback surfaceCallback = new SurfaceHolder.Callback() {
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
camera.stopPreview();
camera.release();
camera = null;
}
@Override
public void surfaceCreated(SurfaceHolder holder) {          
initCamera();           
}
private Size getOptimalPreviewSize(List<Size> sizes, int w, int h) {
final double ASPECT_TOLERANCE = 0.2;
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.d(TAG, "Checking size " + size.width + "w " + size.height
+ "h");
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;
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
Camera.Parameters parameters = camera.getParameters();
List<Size> sizes = parameters.getSupportedPreviewSizes();
Size optimalSize = getOptimalPreviewSize(sizes, width, height);         
Log.d(TAG, "Surface size is " + width + "w " + height + "h");
Log.d(TAG, "Optimal size is " + optimalSize.width + "w " + optimalSize.height + "h");           
parameters.setPreviewSize(optimalSize.width, optimalSize.height);           
//parameters.setPreviewSize(width, height);            
camera.setParameters(parameters);
camera.startPreview();
}
};  
  • AFAIK la vista previa de la cámara sólo funciona realmente en el paisaje, al menos para 2.2 y versiones anteriores. Supongo que es por eso que las actividades que hacemos previa de la cámara tienden a ocultar el sistema de notificación de la barra y no tienen títulos… a pesar de ser aparentemente retrato creo que son «realmente» el paisaje.
InformationsquelleAutor Abhinav | 2011-01-10

7 Comentarios

  1. 71

    Procedentes de otros estados y mi problema:

    La Rotación de la cámara problema dependerá de los diferentes Dispositivos y ciertos Versión.

    Versión 1.6: para corregir la Rotación de la Cuestión, y es bueno para la mayoría de los dispositivos

    if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT)
    {   
    p.set("orientation", "portrait");
    p.set("rotation",90);
    }
    if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE)
    {                               
    p.set("orientation", "landscape");          
    p.set("rotation", 90);
    }

    Versión 2.1: dependen del tipo de dispositivos, por ejemplo, Cannt solucionar el problema con el XPeria X10, pero es bueno para el X8, y Mini

    Camera.Parameters parameters = camera.getParameters();
    parameters.set("orientation", "portrait");
    camera.setParameters(parameters);

    Versión 2.2: no para todos los dispositivos

    camera.setDisplayOrientation(90);

    http://code.google.com/p/android/issues/detail?id=1193#c42

    • Que problema resuelto.
    • ¿qué significa para ti la versión aquí?
  2. 32

    De los Javadocs para setDisplayOrientation(int) (Requiere nivel de API 9):

     public static void setCameraDisplayOrientation(Activity activity,
    int cameraId, android.hardware.Camera camera) {
    android.hardware.Camera.CameraInfo info =
    new android.hardware.Camera.CameraInfo();
    android.hardware.Camera.getCameraInfo(cameraId, info);
    int rotation = activity.getWindowManager().getDefaultDisplay()
    .getRotation();
    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);
    }
    • La clase CameraInfo no fue introducido hasta el nivel de la API 9, así que el método que he publicado requiere de la API de nivel 9.
    • no su trabajo para la nexus 7 ….qué hacer ??/
    • result = (360 - result) % 360; // compensate the mirror debe ser eliminado, las imágenes de la cámara frontal son de otra manera girar incorrectamente
    • ¿has comprobado esto en varios dispositivos? He utilizado este código para la rotación de un número de veces y todavía no han encontrado una rotación incorrecta.
    • de la cámara.setDisplayOrientation no funciona en algunos dispositivos
    • Se requiere nivel de API 9
    • Jason Robinson tengo algunos modelos de la lista de api en la que el nivel está por encima de 9, pero aún este método no tiene ningún efecto. No sabe el tiempo de su hardware relacionados con el tema. Lista de dispositivos rotation_issue_models = Arrays.asList(«GT-S5360», «GT-S6802», «GT-S5830C», «GT-S5830I», «DROID2», «GLOBAL», «XT557», «Deseo » HD», «PC36100», «GT-I9000», «ADR6350», «Mi-One Plus», «SGH-T989», «GT-I9100», «GT-I9001»);
    • ¿cuál sería el cameraId parámetro. yo no entiendo esto
    • La mirada en developer.android.com/reference/android/hardware/…, particularmente CAMERA_FACING_BACK y CAMERA_FACING_FRONT.
    • Gracias. tengo
    • ¿puedes resolver el problema con los dispositivos?
    • Ninguna cámara.setDisplayOrientation no funciona correctamente en algunos dispositivos, como el Samsung y Samsung Ace. incluso se han API de nivel mayor que 9
    • Puede ser su mejor poner específico de dispositivo de cheques?

  3. 25

    Esta solución funciona para todos versiones de Android. Usted puede utilizar la reflexión en Java para hacer que funcione para todos los dispositivos Android:

    Básicamente, usted debe crear un reflejo de contenedor para llamar al Android 2.2 setDisplayOrientation, en lugar de llamar al método específico.

    El método:

        protected void setDisplayOrientation(Camera camera, int angle){
    Method downPolymorphic;
    try
    {
    downPolymorphic = camera.getClass().getMethod("setDisplayOrientation", new Class[] { int.class });
    if (downPolymorphic != null)
    downPolymorphic.invoke(camera, new Object[] { angle });
    }
    catch (Exception e1)
    {
    }
    }

    Y en lugar de utilizar de la cámara.setDisplayOrientation(x) uso setDisplayOrientation(cámara, x) :

        if (Integer.parseInt(Build.VERSION.SDK) >= 8)
    setDisplayOrientation(mCamera, 90);
    else
    {
    if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT)
    {
    p.set("orientation", "portrait");
    p.set("rotation", 90);
    }
    if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE)
    {
    p.set("orientation", "landscape");
    p.set("rotation", 90);
    }
    }   
    • La otra parte no funciona en algunos 2.1 dispositivos, pero no TODOS (ver maydenec la explicación anterior).
    • Cual es el tipo de p?
    • Creo que p es de typre Camera.Parameters. Trate de añadir la siguiente línea: Camera.Parameters p = camera.getParameters();
  4. 6

    Me enfrenté el problema, cuando yo estaba usando ZBar para la digitalización de las fichas.
    La orientación de la cámara cuestión. Utilizando el código de abajo, yo era capaz de resolver el problema.
    Esto no es todo el fragmento de código, por Favor, tome sólo la ayuda de este.

     public void surfaceChanged(SurfaceHolder holder, int format, int width,
    int height) {
    if (isPreviewRunning) {
    mCamera.stopPreview();
    }
    setCameraDisplayOrientation(mCamera);
    previewCamera();
    }
    public void previewCamera() {
    try {
    //Hard code camera surface rotation 90 degs to match Activity view
    //in portrait
    mCamera.setPreviewDisplay(mHolder);
    mCamera.setPreviewCallback(previewCallback);
    mCamera.startPreview();
    mCamera.autoFocus(autoFocusCallback);
    isPreviewRunning = true;
    } catch (Exception e) {
    Log.d("DBG", "Error starting camera preview: " + e.getMessage());
    }
    }
    public void setCameraDisplayOrientation(android.hardware.Camera camera) {
    Camera.Parameters parameters = camera.getParameters();
    android.hardware.Camera.CameraInfo camInfo =
    new android.hardware.Camera.CameraInfo();
    android.hardware.Camera.getCameraInfo(getBackFacingCameraId(), camInfo);
    Display display = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
    int rotation = display.getRotation();
    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 (camInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
    result = (camInfo.orientation + degrees) % 360;
    result = (360 - result) % 360;  //compensate the mirror
    } else {  //back-facing
    result = (camInfo.orientation - degrees + 360) % 360;
    }
    camera.setDisplayOrientation(result);
    }
    private int getBackFacingCameraId() {
    int cameraId = -1;
    //Search for the front facing camera
    int numberOfCameras = Camera.getNumberOfCameras();
    for (int i = 0; i < numberOfCameras; i++) {
    Camera.CameraInfo info = new Camera.CameraInfo();
    Camera.getCameraInfo(i, info);
    if (info.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {
    cameraId = i;
    break;
    }
    }
    return cameraId;
    }
  5. 5

    Finalmente me fijo esta usando el Google de la aplicación de la cámara. Se pone la orientación del teléfono mediante el uso de un sensor y, a continuación, establece la etiqueta EXIF de forma adecuada. El JPEG que sale de la cámara no está orientada de forma automática.

    También, la vista previa de la cámara funciona correctamente sólo en el modo de paisaje. Si usted necesita que su actividad de diseño para ser orientado en vertical, tendrá que hacerlo de forma manual utilizando el valor de la orientación del sensor.

    • hey, cómo conseguir el la orientación de la cámara utilizando el sensor de orientación ?? por favor, comparta su código…
    • ver en este enlace stackoverflow.com/questions/9055460/…
    • Gracias por la Ayuda,pero mi problema es cuando estoy tomando fotos en symsung teléfonos en el modo de retrato en ese momento de la foto se muestra de 90 grados de rotación en la pantalla de mi. Así que, yo estoy tratando de conseguir la orientación de la cámara, i m girar la foto 90 grados para el modo de retrato
  6. 4

    Este problema fue resuelto hace mucho tiempo, pero he encontrado algunas dificultades para poner todas las piezas juntas así que aquí está mi solución final, espero que esto ayude a otros :

    public void startPreview() {
    try {
    Log.i(TAG, "starting preview: " + started);
    //....
    Camera.CameraInfo camInfo = new Camera.CameraInfo();
    Camera.getCameraInfo(cameraIndex, camInfo);
    int cameraRotationOffset = camInfo.orientation;
    //...
    Camera.Parameters parameters = camera.getParameters();
    List<Camera.Size> previewSizes = parameters.getSupportedPreviewSizes();
    Camera.Size previewSize = null;
    float closestRatio = Float.MAX_VALUE;
    int targetPreviewWidth = isLandscape() ? getWidth() : getHeight();
    int targetPreviewHeight = isLandscape() ? getHeight() : getWidth();
    float targetRatio = targetPreviewWidth / (float) targetPreviewHeight;
    Log.v(TAG, "target size: " + targetPreviewWidth + " /" + targetPreviewHeight + " ratio:" + targetRatio);
    for (Camera.Size candidateSize : previewSizes) {
    float whRatio = candidateSize.width / (float) candidateSize.height;
    if (previewSize == null || Math.abs(targetRatio - whRatio) < Math.abs(targetRatio - closestRatio)) {
    closestRatio = whRatio;
    previewSize = candidateSize;
    }
    }
    int rotation = getWindowManager().getDefaultDisplay().getRotation();
    int degrees = 0;
    switch (rotation) {
    case Surface.ROTATION_0:
    degrees = 0;
    break; //Natural orientation
    case Surface.ROTATION_90:
    degrees = 90;
    break; //Landscape left
    case Surface.ROTATION_180:
    degrees = 180;
    break;//Upside down
    case Surface.ROTATION_270:
    degrees = 270;
    break;//Landscape right
    }
    int displayRotation;
    if (isFrontFacingCam) {
    displayRotation = (cameraRotationOffset + degrees) % 360;
    displayRotation = (360 - displayRotation) % 360; //compensate
    //the
    //mirror
    } else { //back-facing
    displayRotation = (cameraRotationOffset - degrees + 360) % 360;
    }
    Log.v(TAG, "rotation cam /phone = displayRotation: " + cameraRotationOffset + " /" + degrees + " = "
    + displayRotation);
    this.camera.setDisplayOrientation(displayRotation);
    int rotate;
    if (isFrontFacingCam) {
    rotate = (360 + cameraRotationOffset + degrees) % 360;
    } else {
    rotate = (360 + cameraRotationOffset - degrees) % 360;
    }
    Log.v(TAG, "screenshot rotation: " + cameraRotationOffset + " /" + degrees + " = " + rotate);
    Log.v(TAG, "preview size: " + previewSize.width + " /" + previewSize.height);
    parameters.setPreviewSize(previewSize.width, previewSize.height);
    parameters.setRotation(rotate);
    camera.setParameters(parameters);
    camera.setPreviewDisplay(mHolder);
    camera.startPreview();
    Log.d(TAG, "preview started");
    started = true;
    } catch (IOException e) {
    Log.d(TAG, "Error setting camera preview: " + e.getMessage());
    }
    }
    • «Yo espero que esto ayude a otros No, es no. Su pieza de código se sacó de contexto. Por ejemplo, ¿dónde está el ‘isFrontFacingCam’ viene?
    • Creo que este es otro de los temas que en realidad, esto no es nada en comparación con el problema inicial. Usted puede obtener de android.de hardware.De la cámara.CameraInfo.enfrenta == CameraInfo.CAMERA_FACING_FRONT. Lo siento acerca de esto.
  7. 4

    retirar esta solución

     public static void setCameraDisplayOrientation(Activity activity,
    int cameraId, android.hardware.Camera camera) {
    android.hardware.Camera.CameraInfo info =
    new android.hardware.Camera.CameraInfo();
    android.hardware.Camera.getCameraInfo(cameraId, info);
    int rotation = activity.getWindowManager().getDefaultDisplay()
    .getRotation();
    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);
    }
    • Gracias por el manejo de la cámara frontal. Esta solucionado mi problema
    • usted es bienvenido @LouisCAD feliz de ver que mi solución a resolver su problema.

Dejar respuesta

Please enter your comment!
Please enter your name here