2016-10-03 4 views
1

Ich habe ein schlechtes Verhalten bei der Aufnahme eines Fotos auf einem Samsung Galaxy S7 Edge-Gerät.camera2 Bilder gemacht sind verschwommen

Ich warte vor der Aufnahme gleichzeitig auf Fokus und Belichtung, aber am Ende habe ich eine Art verschwommenes Bild im Vergleich zur nativen Kamera-App-Ausgabe.

Das Problem ist besonders bei gezoomten Bildern sichtbar, aber auch bei nicht gezoomten Bildern. Ich habe auch versucht, die optische Bildstabilisierung zu ermöglichen, aber das Problem ist nicht behoben.

Im Folgenden finden Sie Beispiele, die das Problem erklären.

Native camera image

My camera image

Hier ist der Code:

Verfahren zur Bildaufnahme Schritt 1:

public void capturePicture() { 
    CameraState state = getState(); 
    if (state != IDLE && state != CLOSING && state != TAKE_PICTURE) { 
      boolean af = false; 
      boolean ae = false; 
      if (isAFEnabled()) { 
       af = true; 
      } else if (isAEEnabled()) { 
       ae = true; 
      } 

      if (!af && !ae) { 
       takePicture(); 
      } else { 
       triggerFocusAndExposure(true); 
      } 
    } 

    return; 
} 

Verfahren zur Fokussierung und Belichtung auslösenden:

private void triggerFocusAndExposure(boolean picture) { 
    setState(WAIT_PRECAPTURE_PICTURE); 

    if (isAFEnabled()) { 
     previewBuilder.set(CONTROL_AF_TRIGGER, CONTROL_AF_TRIGGER_START); 
    } 

    if (isAEEnabled()) { 
     previewBuilder.set(CONTROL_AE_PRECAPTURE_TRIGGER, CONTROL_AE_PRECAPTURE_TRIGGER_START); 
    } 

    try { 
     cameraSession.capture(previewBuilder.build(), new SCameraCaptureSession.CaptureCallback() { 
      @Override public void onCaptureCompleted(SCameraCaptureSession session, SCaptureRequest request, STotalCaptureResult result) { 
       setState(PRECAPTURE_TRIGGERED_PICTURE); 
      } 
     }, backgroundHandler); 
    } catch (CameraAccessException e) { 
     return; 
    } 

    try { 
     previewBuilder.set(CONTROL_AF_TRIGGER, CONTROL_AF_TRIGGER_IDLE); 
     previewBuilder.set(CONTROL_AE_PRECAPTURE_TRIGGER, CONTROL_AE_PRECAPTURE_TRIGGER_IDLE); 
     cameraSession.setRepeatingRequest(previewBuilder.build(), mSessionCaptureCallback, backgroundHandler); 
    } catch (CameraAccessException e) { 
    } 
} 
Fokus und Belichtung

Methoden für die Warte:

private void waitPrecapture(STotalCaptureResult result, boolean picture) { 
    // Check if AF/AE triggered and/or finished 
    if ((!isAFTriggered(result) || isAfFinished(result)) && (!isAETriggered(result) || isAEFinished(result))) { 
     takePicture(); 
    } 
} 

private boolean isAFTriggered(STotalCaptureResult result) { 
    Integer afMode = result.get(SCaptureResult.CONTROL_AF_MODE); 
    return afMode != CONTROL_AF_MODE_OFF && 
      afMode != CONTROL_AF_MODE_EDOF; 
} 

private boolean isAfFinished(STotalCaptureResult result) { 
    int afState = result.get(SCaptureResult.CONTROL_AF_STATE); 
    return afState == CONTROL_AF_STATE_FOCUSED_LOCKED || afState == CONTROL_AF_STATE_NOT_FOCUSED_LOCKED 
      || afState == CONTROL_AF_STATE_PASSIVE_FOCUSED || afState == CONTROL_AF_STATE_PASSIVE_UNFOCUSED; 
} 

private boolean isAETriggered(STotalCaptureResult result) { 
    boolean aeMode = result.get(SCaptureResult.CONTROL_AE_MODE) != SCaptureResult.CONTROL_AE_MODE_OFF; 
    return aeMode && cameraCharacteristics.get(SCameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL) 
      != SCameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY; 
} 

private boolean isAEFinished(STotalCaptureResult result) { 
    Integer aeState = result.get(SCaptureResult.CONTROL_AE_STATE); 
    return aeState == null || aeState == SCaptureResult.CONTROL_AE_STATE_CONVERGED || aeState == SCaptureResult.CONTROL_AE_STATE_FLASH_REQUIRED 
      || aeState == SCaptureResult.CONTROL_AE_STATE_LOCKED; 
} 

Verfahren zur Bildaufnahme Schritt 2:

public void takePicture(){ 
    imageReader.setOnImageAvailableListener(reader -> { 
     Image image = reader.acquireLatestImage(); 
     ByteBuffer buffer = image.getPlanes()[0].getBuffer(); 
     byte[] bytes = new byte[buffer.remaining()]; 
     buffer.get(bytes); 
     image.close(); 
     singleSubscriber.onSuccess(bytes); 
    }, imageSavingHandler); 

    try { 
     cameraSession.capture(captureBuilder.build(), new SCameraCaptureSession.CaptureCallback() { 
      @Override 
      public void onCaptureCompleted(SCameraCaptureSession session, SCaptureRequest request, STotalCaptureResult result) { 
       if (getState() == CameraState.CLOSING) { 
        return; 
       } 
       cancelAF(); 
      } 

      @Override 
      public void onCaptureStarted(SCameraCaptureSession session, SCaptureRequest request, long timestamp, long frameNumber) { 
       super.onCaptureStarted(session, request, timestamp, frameNumber); 
       shutterCallback.call(); 
      }  

      @Override public void onCaptureFailed(SCameraCaptureSession session, SCaptureRequest request, SCaptureFailure failure) { 
        singleSubscriber.onError(new RuntimeException("Error taking picture, onCaptureFailed")); 
        if (getState() == CameraState.CLOSING) { 
         return; 
        } 
        cancelAF(); 
      } 
     }, backgroundHandler); 

     setState(CameraState.TAKE_PICTURE); 
    } catch (CameraAccessException e) { 
     singleSubscriber.onError(new RuntimeException("Error capturing image", e)); 
    } 
} 
+0

mehr Code bitte – Vyacheslav

+0

Sehr interessant. Danke. Wofür? Dies ist eine Programmierseite. Ich sehe wenig Programmierung. – greenapps

+0

Welches Tutorial haben Sie für die Bilderfassung verwendet? – abbath

Antwort

7

ich das Update gefunden habe. captureBuilder setzt automatisch CaptureRequest.NOISE_REDUCTION_MODE_HIGH_QUALITY und CaptureRequest.EDGE_MODE_HIGH_QUALITY aber in meinem Fall hat das Gerät einige Probleme mit diesen Optionen. Einstellung CaptureRequest.NOISE_REDUCTION_MODE_FAST und CaptureRequest.EDGE_MODE_FAST behebt das Problem.

Verwandte Themen