El procesamiento de estiramiento de la imagen de la interfaz de vista previa de la cámara, al cambiar el tamaño de la ventana de visualización para adaptarse al tamaño de vista previa de la cámara

1. Prefacio
El control que muestra el marco: SurfaceView.
Relación de tamaño de control: 1: 1 (el tamaño cuadrado es más adecuado para el reconocimiento facial)
Tamaño de la ventana de visualización: pantalla no completa
2. Motivo de estiramiento El
tamaño de vista previa de la cámara se lee de la lista de fabricantes

Camera.Parameters parameters = mCamera.getParameters();
List<Camera.Size> sizeList = parameters.getSupportedPreviewSizes();//获取预览的各种分辨率

Obtenga el mejor tamaño (código fuente del desarrollador de Google)

private Camera.Size getOptimalPreviewSize(List<Camera.Size> sizes, int w, int h) {
    final double ASPECT_TOLERANCE = 0.1;
    double targetRatio;
    if (w > h) {
        targetRatio = (double) w / h;  /* w / h : 横向   h / w :竖向*/
    } else {
        targetRatio = (double) h / w;  /* w / h : 横向   h / w :竖向*/
    }
    if (sizes == null) return null;

    Camera.Size optimalSize = null;
    double minDiff = Double.MAX_VALUE;

    int targetHeight = h;

    for (Camera.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);
        }
    }

    if (optimalSize == null) {
        minDiff = Double.MAX_VALUE;
        for (Camera.Size size : sizes) {
            if (Math.abs(size.height - targetHeight) < minDiff) {
                optimalSize = size;
                minDiff = Math.abs(size.height - targetHeight);
            }
        }
    }
    Log.e(TAG, "finally choose size:optimalSize width=" + optimalSize.width + "   optimalSize height=" + optimalSize.height);
    return optimalSize;

}

Se llama completamente el código fuente de Google y no ha cambiado.
Entonces, ¿qué sucede si la relación de aspecto de todos los tamaños en la lista de lectura no satisface nuestra ventana?
Por supuesto, es la deformación de la interfaz de vista previa. Si no se cumple la relación, el tamaño seleccionado puede ser mayor de lo que esperábamos. Por ejemplo,
el tamaño de nuestra ventana de vista previa es: 800x800, y el tamaño de vista previa de la cámara seleccionada es: 1280x720, que es más grande que el tamaño de la ventana. Comprima y estire cuando sea pequeño para compensar la falta de píxeles.
3. La solución es cambiar dinámicamente el tamaño de la ventana para adaptarse al tamaño de vista previa de la cámara.
Tomando el tamaño anterior como ejemplo, la ventana de vista previa cuadrada no obtiene un tamaño 1: 1 en algunos teléfonos móviles.
En este momento, debe ajustar su propia proporción de ventana. Si no desea ser demasiado diferente del tamaño de ventana original, elija una proporción de 4: 3 (la situación específica debe determinarse de acuerdo con su proyecto).
Ventana de 800x800, después del ajuste, 800x600

private boolean surfaceChanged = true;

Defina una variable global para controlar si el surfaceView necesita ser ajustado. Si no lo necesita, no necesita agregarlo, pero tenga en cuenta que surfaceChanged se llamará de forma invisible aquí. Si hay un método de ajuste llamado en el reescribir el método de SurfaceView, debe hacerlo, de lo contrario, se repetirá sin fin.

double ratioSurface = (double) surfaceView.getWidth() / (double) surfaceView.getHeight();
double ratioCamera = (double) optionSize.width / (double) optionSize.height;
Log.v(TAG, "ratioSurface:" + ratioSurface + "    ratioCamera:" + ratioCamera);
if (surfaceChanged && ratioCamera != ratioSurface) {
   RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(600, 800);//这里根据自己的需要,是竖屏还是横屏,我们是竖屏,所以选择了宽高对换了一下。
   layoutParams.addRule(RelativeLayout.CENTER_IN_PARENT);//这一行是让控件在父控件完全居中
   surfaceView.setLayoutParams(layoutParams);
   surfaceChanged = false;
}

¿Dónde se agrega el código anterior?

 mCamera.setParameters(parameters);

Se puede hacer antes de la configuración de parámetros.
4. Posibles problemas
A. Rotación de la imagen: en
este caso, debe ajustar manualmente la cámara usted mismo.

PD: Dado que esto se escribió cuando se resolvió el problema en el proyecto, no es conveniente cargar el código fuente, pero se estima que el código fuente no es portátil.
Gracias por venir.

Supongo que te gusta

Origin blog.csdn.net/mozushixin_1/article/details/93997938
Recomendado
Clasificación