Estoy en una Aplicación de Cámara que toma básica de imágenes. Tengo un problema cuando llego a la mejor óptimo tamaño de la vista previa.

De hecho, con este primer código :

public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
    if (isPreviewRunning) {
        mCamera.stopPreview();
    }
    Camera.Parameters parameters = mCamera.getParameters();
    mCamera.setParameters(parameters);
    mCamera.startPreview();
    isPreviewRunning = true;
}

La imagen tiene una buena calidad :

http://img689.imageshack.us/i/04042011172937.jpg/

Pero, con este código :

private Size getOptimalPreviewSize(List<Size> sizes, int w, int h) {
final double ASPECT_TOLERANCE = 0.05;
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) {
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;
}
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
//Now that the size is known, set up the camera parameters and begin
//the preview.
if (isPreviewRunning) {
mCamera.stopPreview();
}
Camera.Parameters parameters = mCamera.getParameters();
List<Size> sizes = parameters.getSupportedPreviewSizes();
Size optimalSize = getOptimalPreviewSize(sizes, w, h);
parameters.setPreviewSize(optimalSize.width, optimalSize.height);
mCamera.setParameters(parameters);
mCamera.startPreview();
isPreviewRunning =true;
}

La imagen totalmente distorsionada :

http://img97.imageshack.us/i/04042011173220.jpg/

¿Cómo puedo resolver este problema??

Estoy usando un HTC Desire HD.

Es, probablemente, el método de ahorro ? :

PictureCallback mPictureCallbackJpeg = new PictureCallback() {      
public void onPictureTaken(byte[] imageData, Camera camera) {
....
BitmapFactory.Options options=new BitmapFactory.Options();
options.inSampleSize = 5; 
Bitmap myImage = BitmapFactory.decodeByteArray(imageData, 0,imageData.length,options);
FileOutputStream fOut = new FileOutputStream(path + "/"+fl);
BufferedOutputStream bos = new BufferedOutputStream(fOut);
myImage.compress(CompressFormat.JPEG, 100, bos);
bos.flush();
bos.close();
....
}

Gracias

Han resuelto este problema?
Se trata de un viejo proyecto, pero parece que Seantron el código funciona. Probarlo 😉

OriginalEl autor jc_35 | 2011-04-04

2 Comentarios

  1. 26

    Yo sólo sufrieron el mismo problema, y se me ocurrió algo similar, pero más ligero peso de la solución. Yo no veo nada malo con su método de ahorro, sin embargo.

    private Camera.Size getBestPreviewSize(int width, int height)
    {
    Camera.Size result=null;    
    Camera.Parameters p = camera.getParameters();
    for (Camera.Size size : p.getSupportedPreviewSizes()) {
    if (size.width<=width && size.height<=height) {
    if (result==null) {
    result=size;
    } else {
    int resultArea=result.width*result.height;
    int newArea=size.width*size.height;
    if (newArea>resultArea) {
    result=size;
    }
    }
    }
    }
    return result;
    }
    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
    //This line helped me set the preview Display Orientation to Portrait
    //Only works API Level 8 and higher unfortunately.
    camera.setDisplayOrientation(90);
    Camera.Parameters parameters = camera.getParameters();
    Camera.Size size = getBestPreviewSize(width, height);
    parameters.setPreviewSize(size.width, size.height);
    camera.setParameters(parameters);
    camera.startPreview();
    }
    He tenido un problema con getOptimalPreviewSize en HTC Desire. Función getSupportedPreviewSizes devuelve tamaños: 1280×720, 840×480, 768:432, etc. Llame getOptimalPreviewSize(480,800) devuelve 1280×720. Como resultado, la llamada de setPreviewDisplay se bloquea la aplicación (es necesario reiniciar el dispositivo para restaurar la funcionalidad de la cámara). Como resultado, he utilizado getBestPreviewSize con una pequeña modificación: si ((tamaño.ancho <= ancho && tamaño de.la altura de la <= altura) || (tamaño.la altura de la <= ancho && tamaño de.ancho <= altura)) { … funciona bien.
    Otra razón por la que odio a Android dev, pero gracias por la info. Que OS en el HTC Desire por el camino?
    Era el Deseo de HTC con Android 2.2.2

    OriginalEl autor Seantron

  2. 5

    La mejor manera es conseguir el tamaño de la vista previa con la más cercana relación de aspecto:

    Camera.Size getBestPreviewSize(int width, int height, Camera.Parameters parameters) {
    Camera.Size result=null;
    float dr = Float.MAX_VALUE;
    float ratio = (float)width/(float)height;
    for (Camera.Size size : parameters.getSupportedPreviewSizes()) {
    float r = (float)size.width/(float)size.height;
    if( Math.abs(r - ratio) < dr && size.width <= width && size.height <= height ) {
    dr = Math.abs(r - ratio);
    result = size;
    }
    }
    return result;
    }

    Donde los parámetros width y height son su tamaño de la superficie.

    Esto no mostrar la relación de aspecto correcta, pero cuando se captura la foto de sus cultivos de los lados de la misma. ¿Cómo usted va sobre la prevención de que eso suceda?
    Mismo pasa conmigo. Voluntad, pudiste resolver tu problema?
    usted también debe elegir el tamaño de la imagen de la lista devuelta de getSupportedPictureSizes(). Este tamaño puede ser diferente de la elegida tamaño de la vista previa (generalmente más grandes), pero debe mantener la misma relación de aspecto.

    OriginalEl autor Max

Dejar respuesta

Please enter your comment!
Please enter your name here