OK, ich denke, dass ich das herausgefunden habe. Es gab ein paar Stücke zum sprichwörtlichen Puzzle und ich danke @kcoppock für die Einsicht, die mir geholfen hat, etwas davon zu lösen.
Zuerst müssen Sie die Ausrichtung berücksichtigen, wenn Sie bestimmen, welche Vorschaugröße ausgewählt werden soll. Zum Beispiel ist die getOptimalPreviewSize()
aus der CameraPreview
von ApiDemos
Orientierungslosigkeit, einfach weil ihre Version der App die Ausrichtung auf Landschaft gesperrt hat. Wenn Sie die Ausrichtung frei lassen möchten, müssen Sie das Zielseitenverhältnis umkehren, damit es übereinstimmt. Also, wo getOptimalPreviewSize()
hat:
double targetRatio=(double)width/height;
Sie auch benötigen:
if (displayOrientation == 90 || displayOrientation == 270) {
targetRatio=(double)height/width;
}
wo displayOrientation
ist ein Wert von 0 bis 360, dass ich von etwa 100 Zeilen einig ernsthaft hässlich Code bin Bestimmung, Deshalb verpacke ich all das in eine wiederverwendbare Komponente, die ich in Kürze veröffentlichen werde.Dieser Code basiert auf the setDisplayOrientation()
JavaDocs und this StackOverflow answer.
(BTW, wenn Sie diese nach dem 1. Juli 2013 lesen, und Sie nicht über einen Link in dieser Antwort auf diese Komponente sehen, schreiben Sie einen Kommentar, mich zu erinnern, wie ich vergessen)
Zweitens Sie Sie müssen diese Anzeigeausrichtung berücksichtigen, wenn Sie das Seitenverhältnis des von Ihnen verwendeten Bildformats SurfaceView
/TextureView
steuern. Die CameraPreview
Aktivität von ApiDemos
hat seine eigene Preview
ViewGroup
, die das Seitenverhältnis behandelt, und es müssen Sie das Seitenverhältnis für den Einsatz im Hochformat umgekehrt:
if (displayOrientation == 90
|| displayOrientation == 270) {
previewWidth=mPreviewSize.height;
previewHeight=mPreviewSize.width;
}
else {
previewWidth=mPreviewSize.width;
previewHeight=mPreviewSize.height;
}
wo displayOrientation
ist, dass gleiche Wert (90
und 270
sein Porträt und Reverse-Portrait, und beachten Sie, dass ich nicht versucht habe, Reverse-Portrait oder Reverse-Landscape zu arbeiten, so dass mehr Feinabstimmung erforderlich ist).
Drittens - und eine, die ich ärgerlich finde - müssen Sie die Vorschau vor dem Aufruf setPictureSize()
auf dem Camera.Parameters
starten. Ansonsten ist es so, als ob das Bildseitenverhältnis des Bildes auf die Vorschaubilder angewendet wird, was die Dinge versaut.
So habe ich Code zu haben, ähnelt die folgenden:
Camera.Parameters parameters=camera.getParameters();
Camera.Size pictureSize=getHost().getPictureSize(parameters);
parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
parameters.setPictureSize(pictureSize.width, pictureSize.height);
parameters.setPictureFormat(ImageFormat.JPEG);
camera.setParameters(parameters);
camera.startPreview();
und das ist falsch. Was Sie wirklich brauchen, ist:
Camera.Parameters parameters=camera.getParameters();
Camera.Size pictureSize=getHost().getPictureSize(parameters);
parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
camera.setParameters(parameters);
camera.startPreview();
parameters=camera.getParameters();
parameters.setPictureSize(pictureSize.width, pictureSize.height);
parameters.setPictureFormat(ImageFormat.JPEG);
camera.setParameters(parameters);
Ohne diese Änderung würde ich ein gestrecktes Seitenverhältnis erhalten, auch in der Landschaft. Dies war kein Problem für CameraPreview
von ApiDemos
, da sie keine Bilder machten, und so riefen sie nie setPictureSize()
.
Aber bis jetzt, auf einem Nexus 4, habe ich jetzt quadratische Seitenverhältnisse für Hoch-und Querformat, mit einer schwebenden Ausrichtung (d. H. Nicht auf Querformat gesperrt).
Ich werde versuchen, sich daran zu erinnern, diese Frage zu ändern, wenn ich in andere Hacks von Angehörigen anderer Geräte erforderlich ist, plus meine CameraView
/CameraFragment
Komponenten zu verbinden, wenn sie freigegeben werden.
UPDATE # 1
Nun, natürlich, kann es nicht möglicherweise durch fast diese einfach. :-)
Die Lösung für das Problem, wo setPictureSize()
verschraubt das Seitenverhältnis funktioniert ... bis Sie ein Bild machen. Zu diesem Zeitpunkt wechselt die Vorschau in das falsche Seitenverhältnis.
Eine Möglichkeit wäre, Bilder auf Bilder mit demselben (oder sehr nahen) Seitenverhältnis zur Vorschau zu beschränken, so dass der Schluckauf nicht existiert. Ich mag diese Antwort nicht, da der Benutzer in der Lage sein sollte, die Bildgröße zu erreichen, die die Kamera bietet.
Sie den Umfang des Schadens begrenzen durch:
- Nur die Bildgröße zu aktualisieren, usw.die
Camera.Parameters
kurz vor dem Bild
- Zurückkehren zu der Pre-Bildaufnahme
Camera.Parameters
nach der Einnahme der Bild
Dieses noch stellt das falsche Seitenverhältnis während der Momente, während das Bild aufgenommen wird, nehmen. Die langfristige Lösung dafür - denke ich - besteht darin, die Kameravorschau während der Aufnahme vorübergehend durch ein Standbild (das letzte Vorschaubild) zu ersetzen. Ich werde es irgendwann versuchen.
UPDATE # 2: v0.0.1 von my CWAC-Camera library ist jetzt verfügbar, die oben genannte Code enthält.
finde ich http://stackoverflow.com/questions/6710573/camera-display-doesnt-maintain-aspect-ratio -seems-skewed sag mir, wenn es so ist, werde ich eine vollständige Antwort schreiben – idan
@idan: Sorry, aber es gibt keine Aktionsleiste auf "CameraPreview" in den "ApiDemos". Es verwendet bereits 'Window.FEATURE_NO_TITLE'. Trotzdem danke! – CommonsWare
Ich habe vor kurzem selbst viel daran gearbeitet. Eine Sache, die Sie im Auge behalten sollten (und vielleicht sind Sie es bereits), ist, dass die Vorschaugrößen beim Drehen auf Hochformat nicht die Abmessungen vertauschen. Wenn die Standardausrichtung der Kamera auf Querformat eingestellt ist, entspricht die Breite der Breite des Telefons in Querformat, unabhängig davon, ob Sie tatsächlich * in * Querformat sind. Daher müssen Sie möglicherweise die Breite/Höhe ändern, wenn Sie nach dem suchen korrekte Vorschaugröße – kcoppock