2016-06-06 1 views
3

Je rencontre un problème avec mon application pour appareil photo. Mon application a:Problème d'aperçu de caméra personnalisé (Stretch)

1) un CameraActivity.class et

2) un CameraPreview.class.

CameraPreview mettre en œuvre un surfaceView où il est appelé de CameraActivity pour l'aperçu réel. (Aussi dans CameraActivity J'ai les paramètres)

Maintenant le problème: Lorsque l'aperçu commence, l'aperçu est étiré. J'ai essayé beaucoup de choses (tellement de choses que je ne me souviens pas) J'ai besoin de quelqu'un pour me dire quoi écrire et où. Merci d'avance.

Voici le CameraActivity (pas tout le code, mais l'important, je pense)

private PictureCallback mPicture = new PictureCallback() { 

    public void onPictureTaken(byte[] data, Camera camera) { 

     // Replacing the button after a photho was taken. 
     flBtnContainer.setVisibility(View.GONE); 
     ibRetake.setVisibility(View.VISIBLE); 
     ibUse.setVisibility(View.VISIBLE); 

     // File name of the image that we just took. 
     fileName = "IMG_" + new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()).toString() + ".jpg"; 

     // Creating the directory where to save the image. Sadly in older 
     // version of Android we can not get the Media catalog name 
     File mkDir = new File(sdRoot, dir); 
     mkDir.mkdirs(); 

     // Main file where to save the data that we recive from the camera 
     File pictureFile = new File(sdRoot, dir + fileName); 

     try { 
      FileOutputStream purge = new FileOutputStream(pictureFile); 
      purge.write(data); 
      purge.close(); 
     } catch (FileNotFoundException e) { 
      Log.d("DG_DEBUG", "File not found: " + e.getMessage()); 
     } catch (IOException e) { 
      Log.d("DG_DEBUG", "Error accessing file: " + e.getMessage()); 
     } 

     // Adding Exif data for the orientation. For some strange reason the 
     // ExifInterface class takes a string instead of a file. 
     try { 
      exif = new ExifInterface("/sdcard/" + dir + fileName); 
      exif.setAttribute(ExifInterface.TAG_ORIENTATION, "" + orientation); 
      exif.saveAttributes(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
     Intent intent = new Intent(CameraActivity.this, PicturePreview.class); 
     Bundle extras = new Bundle(); 
     extras.putString("ImagePath", String.valueOf(pictureFile)); 
     intent.putExtras(extras); 
     startActivity(intent); 

     //SendBroadcasts let's us instantly update the SD card with our image 
     sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.parse("file://"+Environment.getExternalStorageDirectory()))); 

    } 



}; 



private void createCamera() { 
    // Create an instance of Camera 
    mCamera = getCameraInstance(); 

//  Setting the right parameters in the camera 
    Camera.Parameters params = mCamera.getParameters(); 
    params.setRotation(90); 
    mCamera.setParameters(params); 

    // Create our Preview view and set it as the content of our activity. 
    mPreview = new CameraPreview(this, mCamera); 
    FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview); 
    preview.addView(mPreview, 0); 
} 


@Override 
protected void onResume() { 
    super.onResume(); 

    // Test if there is a camera on the device and if the SD card is 
    // mounted. 
    if (!checkCameraHardware(this)) { 
     Intent i = new Intent(this, NoCamera.class); 
     startActivity(i); 
     finish(); 
    } else if (!checkSDCard()) { 
     Intent i = new Intent(this, NoSDCard.class); 
     startActivity(i); 
     finish(); 
    } 

    // Creating the camera 
    createCamera(); 

    // Register this class as a listener for the accelerometer sensor 
    ////sensorManager.registerListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_NORMAL); 
} 

@Override 
protected void onPause() { 
    super.onPause(); 
    // release the camera immediately on pause event 
    releaseCamera(); 

    // removing the inserted view - so when we come back to the app we 
    // won't have the views on top of each other. 
    FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview); 
    preview.removeViewAt(0); 
} 

Et voici le CameraPreview.class

public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback { 
private SurfaceHolder mHolder; 
private Camera mCamera; 
boolean isPreviewRunning = true; 




public CameraPreview(Context context, Camera camera) { 
    super(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); 
    mHolder.setFixedSize(100, 100); 

} 

public void surfaceCreated(SurfaceHolder holder) { 
    // The Surface has been created, now tell the camera where to draw the 
    // preview. 
    try { 
     mCamera.setPreviewDisplay(holder); 
     mCamera.setDisplayOrientation(90); 
     mCamera.startPreview(); 
    } catch (IOException e) { 
     Log.d("DG_DEBUG", "Error setting camera preview: " + e.getMessage()); 
    } 

} 

public void surfaceChanged(SurfaceHolder holder, 
          int format, int width, int height) { 


    if (isPreviewRunning){ 
     return; 
    } 
    isPreviewRunning = true; 

    // 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 
    } 




    // make any resize, rotate or reformatting changes here 

    // start preview with new settings 
    try { 
     mCamera.setPreviewDisplay(mHolder); 
     mCamera.startPreview(); 


    } catch (Exception e) { 
     Log.d("DG_DEBUG", "Error starting camera preview: " + e.getMessage()); 
    } 

} 



public void surfaceDestroyed(SurfaceHolder holder) { 
    // empty. Take care of releasing the Camera preview in your activity. 
} 



} 

Quelqu'un peut-il dire ce que je manque? Si possible, je peux discuter sur Facebook ou quelque chose pour une résolution plus rapide de mon problème ..

Mise à jour: @ LikeWhiteOnRice solution.

Voici mon code d'origine

enter image description here

est ici avec le code de LikeWhiteOnRice:

enter image description here

Toute pensée?

+0

Si vous avez besoin de quelque chose d'autre de mon code, dites-moi simplement de le poster ... –

+0

S'il vous plaît ne me guider vers des liens .. Dites-moi juste quoi écrire et où ... –

+0

[link] (http: // i .stack.imgur.com/eu0wu.jpg) Voici mes appareils appareil photo natif –

Répondre

1

J'ai ajouté le code ci-dessous à ma classe d'aperçu de caméra et cela fonctionne pour la plupart des appareils. Juste pour que vous le sachiez, la bibliothèque de caméra dans Android est horrible et une énorme douleur à travailler avec.

Mettez cette fonction dans votre classe CameraPreview:

private Camera.Size getOptimalSize(List<Camera.Size> sizes, int h, int w) { 
    final double ASPECT_TOLERANCE = 0.05; 
    double targetRatio = (double) w/h; 

    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); 
      } 
     } 
    } 

    return optimalSize; 
} 

Dans votre fonction surefaceCreated, ajoutez avant de commencer votre aperçu:

Camera.Parameters cameraParameters = mCamera.getParameters(); 
List<Camera.Size> previewSizes = cameraParameters.getSupportedPreviewSizes(); 
Camera.Size optimalPreviewSize = getOptimalSize(previewSizes, getResources().getDisplayMetrics().widthPixels, getResources().getDisplayMetrics().heightPixels); 
cameraParameters.setPreviewSize(optimalPreviewSize.width, optimalPreviewSize.height); 
mCamera.setParameters(cameraParameters); 

Edit: De plus, je ne sais pas si vous voulez

mHolder.setFixedSize(100, 100); 

dans votre constructeur.

+0

J'ai mis à jour ma question en fonction de votre solution ... –

+0

Et voici comment je l'ai fait .. Vérifiez si vous voulez et dites-moi si son right .. Son mon code dans un fichier txt .. [link] (https://www.sendspace.com/file/wl2k0o) –

+0

Avez-vous essayé de faire votre surface en plein écran, puis en ajoutant votre bouton de capture sur le dessus de celui-ci ?Votre image ne peut pas être déformée si vous utilisez l'écran entier pour l'afficher. – Jay