2012-04-23 11 views
15

Mam tę aplikację, która działa w trybie portretu i jako część jednej czynności Mam obiekt kamery działający jako fragment w nim.Kamera przednia z Androidem odwrócona Zdjęcia

Mam opcję przełączania z kamery przedniej na tylną i podczas robienia zdjęć tylnym aparatem wszystko jest w porządku i dobrze.

Mimo tego, że robię zdjęcia aparatem z przodu, odwrócony zostaje o 180 stopni. Teraz wiem, że to prawdopodobnie ma coś wspólnego z orientacją w trybie portretu, ale posiadanie jej w krajobrazie po prostu zabiłoby pomysł mojej aplikacji.

Czy mimo to można to naprawić, aby wykonane zdjęcie było takie samo jak na podglądzie?

 listener = new OrientationEventListener(this.getActivity(),SensorManager.SENSOR_DELAY_NORMAL){ 

     @Override 
     public void onOrientationChanged(int orientation) { 
      // TODO Auto-generated method stub 
      if (orientation == ORIENTATION_UNKNOWN) return; 
      android.hardware.Camera.CameraInfo info = 
        new android.hardware.Camera.CameraInfo(); 
      android.hardware.Camera.getCameraInfo(mCurrentCamera, info); 
      orientation = (orientation + 45)/90 * 90; 
      int rotation = 0; 
      if (info.facing == CameraInfo.CAMERA_FACING_FRONT) { 
       rotation = (info.orientation - orientation + 360) % 360; 
      } else { // back-facing camera 
       rotation = (info.orientation + orientation) % 360; 
      } 
      if (mCamera.getParameters() != null){ 
      Camera.Parameters mParameters = mCamera.getParameters(); 

      mParameters.setRotation(rotation); 
      mCamera.setParameters(mParameters); 
      } 
     } 

    }; 
    listener.enable(); 
    if (listener.canDetectOrientation()) 
     Log.d("Orientation Possible", "Orientation Possible"); 

Problem polega na tym, że po zrobieniu zdjęcia to się zawiesza. Ponadto, jeśli działa przez chwilę tylko w trybie podglądu, ponownie ulega awarii. Powinienem też chyba dodać, że w innej metodzie robię to.

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


    try{ 
     camera.setParameters(parameters); 
    } 
    catch (RuntimeException ex){ 
     Log.d("Preview", "Failure to set proper parameters"); 
     //need to improve this method 
     if (mSupportedPreviewSizes != null) { 
      Camera.Size cs = mSupportedPreviewSizes.get(0); 
      parameters.setPreviewSize(cs.width, cs.height); 
      camera.setParameters(parameters); 
      requestLayout(); 
      //int tempheight = mPreviewSize.height; 
      //mPreviewSize.height = mPreviewSize.width; 
      //mPreviewSize.width = tempheight; 

     } 
    } 

Jest to wywoływane, gdy przełączasz się między kamerami (odwrotnie do siebie i na odwrót). Czy może to przeszkadzać słuchaczowi wydarzeń orientacyjnych?

Ponadto, podczas zapisywania zrobionego zdjęcia, to jest to, co nazywam. Zanim to było po prostu pobieranie danych jako parametru, ale starałem się, aby również przyjmował orientację ekranu. Problem polega na tym, że orientacja ekranu wynosi zawsze 90, bez względu na wszystko. Mapa bitowa będzie zawsze obrócona o 90 stopni (co jest świetne do robienia zdjęć tylnym aparatem), ale odwraca ją podczas robienia zdjęć za pomocą przedniej kamery. Czy w tej funkcji można zaimplementować poprawkę?

public static Bitmap MakeSquare(byte[] data, int orientation) { 
    int width; 
    int height; 
    // Rotate photo 
    Matrix matrix = new Matrix(); 
    matrix.postRotate(orientation); 
    // Convert ByteArray to Bitmap 
    Bitmap bitPic = BitmapFactory.decodeByteArray(data, 0, data.length); 
    width = bitPic.getWidth(); 
    height = bitPic.getHeight(); 


    // Create new Bitmap out of the old one 
    Bitmap bitPicFinal = Bitmap.createBitmap(bitPic, 0, 0, width, height,matrix, true); 
    bitPic.recycle(); 
    int desWidth; 
    int desHeight; 
    desWidth = bitPicFinal.getWidth(); 
    desHeight = desWidth; 
    Bitmap croppedBitmap = Bitmap.createBitmap(bitPicFinal, 0,bitPicFinal.getHeight()/2 - bitPicFinal.getWidth()/2,desWidth, desHeight); 
    croppedBitmap = Bitmap.createScaledBitmap(croppedBitmap, 528, 528, true); 
    return croppedBitmap; 
} 

Odpowiedz

34

Dobrze. Wygląda na to, że zająłem się tym.Użyłem porady z tego: Android, front and back camera Orientation , Landscape

I zmieniłem funkcję MakeSquare do tego:

public static Bitmap MakeSquare(byte[] data, int cameraID) { 
    int width; 
    int height; 
    Matrix matrix = new Matrix(); 
    Camera.CameraInfo info = new Camera.CameraInfo(); 
    android.hardware.Camera.getCameraInfo(cameraID, info); 
    // Convert ByteArray to Bitmap 
    Bitmap bitPic = BitmapFactory.decodeByteArray(data, 0, data.length); 
    width = bitPic.getWidth(); 
    height = bitPic.getHeight(); 

    // Perform matrix rotations/mirrors depending on camera that took the photo 
    if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) 
    { 
     float[] mirrorY = { -1, 0, 0, 0, 1, 0, 0, 0, 1}; 
     Matrix matrixMirrorY = new Matrix(); 
     matrixMirrorY.setValues(mirrorY); 

     matrix.postConcat(matrixMirrorY); 
    } 

    matrix.postRotate(90); 


    // Create new Bitmap out of the old one 
    Bitmap bitPicFinal = Bitmap.createBitmap(bitPic, 0, 0, width, height,matrix, true); 
    bitPic.recycle(); 
    int desWidth; 
    int desHeight; 
    desWidth = bitPicFinal.getWidth(); 
    desHeight = desWidth; 
    Bitmap croppedBitmap = Bitmap.createBitmap(bitPicFinal, 0,bitPicFinal.getHeight()/2 - bitPicFinal.getWidth()/2,desWidth, desHeight); 
    croppedBitmap = Bitmap.createScaledBitmap(croppedBitmap, 528, 528, true); 
    return croppedBitmap; 
} 

To wydaje się działać i rade. Chociaż nie jestem pewien, czy to był najlepszy sposób, jestem zadowolony z tego. Teraz wszystko, co muszę zrobić, to dowiedzieć się, dlaczego nie przybiera prawidłowego proporcji przy korzystaniu z przedniego aparatu.

+0

Dzięki człowieku! Czy masz jakieś informacje o tym, jak działa to rozwiązanie na "wszystkich" urządzeniach? – marino

+1

Rozwiązany problem z obracaniem obrazu z kamery przedniej (y) –

+0

jest najlepszy .. dzięki – tsanzol

2

Daj te linki spróbować:

http://developer.android.com/reference/android/hardware/Camera.html#setDisplayOrientation(int)

http://developer.android.com/reference/android/hardware/Camera.Parameters.html#setRotation(int)

Konkretnie o to fragment verbiage z linku setRotation.

"Jeśli aplikacje chcą obracać obraz, aby dopasować się do orientacji użytkowników, aplikacje powinny używać OrientationEventListener i Camera.CameraInfo Wartość od OrientationEventListener jest zależna od naturalnej orientacji urządzenia CameraInfo.orientation to kąt między orientacją aparatu a naturalną orientacją urządzenia Suma tych dwóch wartości to kąt obrotu kamery cofania Różnica między nimi jest kątem obrotu kamery przedniej. Należy pamiętać, że zdjęcia w formacie JPEG przednich kamer nie są odbijane lustrzanie jak na wyświetlaczu podglądu. "

Użyłem tego kodu tak jak jest, nie zmodyfikowałem go wcale. Mój aparat jest teraz lepszy, nadal jednak potrzebuje trochę TLC. Też nie mam jeszcze funkcji front-facing.

Powodzenia!

+0

Dzięki, już na nich patrzyłem i próbowałem zaimplementować słuchacza onOrientationChanged w sposób, w jaki radził, ale ciągle pojawiają się awarie. Zmodyfikowałem mój post, aby pokazać mój kod – Valentin