Android Kamera Vorschau gestreckt
Habe ich gearbeitet, auf meine benutzerdefinierte Aktivität der Kamera auf Android, aber wenn die Kamera drehen, das Seitenverhältnis des surface view Durcheinander gebracht.
In meiner oncreate für die Tätigkeit, die ich den framelayout, das hält die Oberfläche der Anzeige mit den Kamera-Parametern.
//FrameLayout that will hold the camera preview
FrameLayout previewHolder = (FrameLayout) findViewById(R.id.camerapreview);
//Setting camera's preview size to the best preview size
Size optimalSize = null;
camera = getCameraInstance();
double aspectRatio = 0;
if(camera != null){
//Setting the camera's aspect ratio
Camera.Parameters parameters = camera.getParameters();
List<Size> sizes = parameters.getSupportedPreviewSizes();
optimalSize = CameraPreview.getOptimalPreviewSize(sizes, getResources().getDisplayMetrics().widthPixels, getResources().getDisplayMetrics().heightPixels);
aspectRatio = (float)optimalSize.width/optimalSize.height;
}
if(optimalSize!= null){
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT, (int)(getResources().getDisplayMetrics().widthPixels*aspectRatio));
previewHolder.setLayoutParams(params);
LayoutParams surfaceParams = new LayoutParams(LayoutParams.MATCH_PARENT, (int)(getResources().getDisplayMetrics().widthPixels*aspectRatio));
cameraPreview.setLayoutParams(surfaceParams);
}
cameraPreview.setCamera(camera);
//Adding the preview to the holder
previewHolder.addView(cameraPreview);
Dann in die Oberfläche Blick ich die Kamera Parameter werden angezeigt
public void setCamera(Camera camera) {
if (mCamera == camera) { return; }
mCamera = camera;
if (mCamera != null) {
requestLayout();
try {
mCamera.setPreviewDisplay(mHolder);
} catch (IOException e) {
e.printStackTrace();
}
if(mCamera != null){
//Setting the camera's aspect ratio
Camera.Parameters parameters = mCamera.getParameters();
List<Size> sizes = parameters.getSupportedPreviewSizes();
Size optimalSize = getOptimalPreviewSize(sizes, getResources().getDisplayMetrics().widthPixels, getResources().getDisplayMetrics().heightPixels);
parameters.setPreviewSize(optimalSize.width, optimalSize.height);
mCamera.setParameters(parameters);
}
/*
Important: Call startPreview() to start updating the preview surface. Preview must
be started before you can take a picture.
*/
mCamera.startPreview();
}
}
Können Sie sehen, dass die LEGO-Männchen wächst größer und dünner, wenn das Telefon gedreht wird:
Wie kann ich sicherstellen, dass das Seitenverhältnis für meine Kamera-Ansicht ist die richtige?
InformationsquelleAutor der Frage scientiffic | 2013-10-24
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ich bin mit dieser Methode -> basierend auf den API-Demos, um mein Album Vorhören Größe:
Wie Sie sehen können Sie die Eingabe von Breite und Höhe des Bildschirms. Diese Methode berechnet Bildschirm-Verhältnis auf der Grundlage dieser Werte und dann aus der Liste der supportedPreviewSizes Sie wählen die besten für Sie aus verfügbar diejenigen. Holen Sie sich Ihre supportedPreviewSize Liste in den Ort, wo Kamera-Objekt nicht null ist, durch Verwendung
Und dann auf in onMeasure können Sie Ihre optimale previewSize so:
Und dann (in meinem code in surfaceChanged Methode, wie ich sagte, ich bin mit API-Demos Struktur CameraActivity code, erzeugen Sie in Eclipse):
Und ein Hinweis für Sie, denn ich habe fast die gleiche app wie Sie. Gute Praxis für die Aktivität der Kamera ist das ausblenden der StatusBar. Anwendungen wie Instagram sind, es zu tun. Es verringert Ihren Bildschirm Wert "Höhe" und ändern Sie Ihr Verhältnis Wert. Es ist möglich, seltsam Vorschau-Größen auf einigen Geräten (Ihr SurfaceView werden Schnitt ein wenig)
Und um Ihre Frage zu beantworten, wie um zu prüfen, ob die Vorschau-Verhältnis ist das richtige? Dann erhalten Sie Höhe und Breite der Parameter, die Sie einstellen, in:
Ihr Verhältnis ist gleich der Höhe/Breite. Wenn Sie möchten, dass die Kamera gut Aussehen auf deinem Bildschirm dann die Höhe/Breite-Verhältnis von Parametern, die Sie festlegen, um die Kamera muss die gleiche sein wie die Höhe(abzüglich Statuszeile)/breiten-Verhältnis des Bildschirms.
InformationsquelleAutor der Antwort F1sher
F1Sher die Lösung ist schön, aber manchmal nicht funktioniert. Besonders, wenn Ihr surfaceView deckt nicht den ganzen Bildschirm. In diesem Fall müssen Sie zum überschreiben onMeasure () - Methode.
Ich habe kopiert mein code hier für Ihre Referenz.
Da ich gemessen surfaceView, basierend auf Breite, dann habe ich etwas weiße Lücke am Ende von meinem Bildschirm, dass ich es ausgefüllt per design. Sie sind in der Lage das Problem zu beheben, wenn Sie halten die Höhe und Zunahme der Breite multiplizieren es zu Verhältnis. Jedoch, es wird Plitsch surfaceView leicht.
InformationsquelleAutor der Antwort Hesam
HINWEIS: MEINE LÖSUNG IST EINE FORTSETZUNG VON HESAM-LÖSUNG: https://stackoverflow.com/a/22758359/1718734
Was ich Adresse: Hesam gesagt, es ist eine kleine, weiße Fläche, die angezeigt werden können auf einige Handys, wie das ist:
Hesam schlug vor, eine zweite Lösung, aber das squishes der Vorschau. Und auf einigen Geräten, ist es stark verzerrt.
So, wie lösen wir das problem. Es ist simple...by die Multiplikation der Seitenverhältnisse, bis es füllt den Bildschirm. Ich habe bemerkt, mehrere populäre apps wie Snapchat, WhatsApp usw. funktioniert auf die gleiche Weise.
Alles, was Sie tun müssen ist, fügen Sie diese, um die Methode onMeasure:
Dadurch wird die Berechnung der Bildschirm-Höhe und bekommt das Verhältnis von Bildschirmhöhe und die mPreviewSize Höhe. Dann multipliziert es die Kamera für die Breite und Höhe durch die neue Höhe-Verhältnis und die Menge der gemessenen dimension entsprechend.
Und das nächste, was Sie wissen, Sie am Ende mit diesem 😀
Dies funktioniert auch gut mit er Kamera an der Vorderseite. Ich glaube, dies ist der beste Weg zu gehen über diese. Nun ist die einzige Sache, die Links für meine app zu speichern, die Vorschau selbst beim Klick auf "Aufnehmen". Aber ja, das ist es.
InformationsquelleAutor der Antwort Yoosuf
OK, also ich denke, es keine ausreichende Antwort für Allgemeine Kamera-Vorschau-stretching-problem. Oder zumindest ich nicht fündig. Meine app hatte auch das dehnen-Syndrom, und es dauerte eine Weile, um Rätsel gemeinsam eine Lösung, von der alle Nutzer, die Antworten auf diesem portal und internet.
Habe ich versucht @Hesam ist Lösung aber es hat nicht funktioniert und verließ meine Kamera Vorschau majorly verzerrt.
Zuerst zeige ich den code von meiner Lösung (die wichtigen Teile des Codes) und dann erkläre ich, warum ich nahm diese Schritte. Es gibt Raum für performance Modifikationen.
Haupttätigkeit xml-layout:
Kamera-Vorschau:
Haupttätigkeit:
Mein Kommentar:
Dem Punkt, der all dies ist, dass, obwohl Sie die Berechnung der optimale Kamera-Größe in
getOptimalPreviewSize()
Sie Holen nur die nächstgelegene Verhältnisum Ihren Bildschirm passen. Es sei denn, das Verhältnis ist genau die gleichen die Vorschau wird Strecken.Warum wird es zu dehnen? Weil Ihr FrameLayout Kamera-Vorschau in layout.xml zu match_parent in Breite und Höhe. So, dass ist der Grund, warum die Vorschau wird gestreckt auf Vollbild.
Was getan werden muss, ist zu set-Kamera-Vorschau-layout Breite und Höhe entsprechend der gewählten - Kamera-Größe-Verhältnisso die Vorschau hält, Seitenverhältnis und nicht verzerren.
Ich habe versucht, die
CameraPreview
Klasse, der alle Berechnungen und layout-änderungen, aber ich konnte nicht es herausfinden. Ich habe versucht, zu gelten diese LösungaberSurfaceView
nicht erkennengetChildCount ()
odergetChildAt (int index)
. Ich denke, ich habe es arbeiten schließlich mit einem Verweis aufmaLayoutPreview
aber es war schlecht benommen und angewendet, das Verhältnis zu meiner ganzen app-und es hat so nach dem ersten Bild aufgenommen wurde. Also ließ ich ihn gehen und zog die änderungen am layout derMainActivity
.In
CameraPreview
ich geändertprSupportedPreviewSizes
undgetOptimalPreviewSize()
zu öffentlichen damit ich Sie inMainActivity
. Dann brauchte ich die display Abmessungen (abzüglich der navigation/status-bar, wenn es einer ist) und der gewählten optimalen Kamera Größe. Ich habe versucht, um das RelativeLayout (oder FrameLayout) Größe statt der display-Größe, aber es wurde wieder den Wert null. Diese Lösung hat bei mir nicht funktioniert. Das layout bekam es Wert ist, nachonWindowFocusChanged
(überprüft in der log).So, ich habe meine Methoden für die Berechnung der layout-Abmessungen zu entsprechen, die das Seitenverhältnis des gewählten Kamera-Größe. Jetzt müssen Sie nur festlegen
LayoutParams
Ihrer Kamera-Vorschau-layout. Ändern Sie die Breite, Höhe und zentrieren Sie es im übergeordneten.Gibt es zwei Möglichkeiten wie die Berechnung der Vorschau die Abmessungen. Entweder man will es, um den Bildschirm passen mit schwarzen Balken (wenn windowBackground auf null gesetzt ist) an den Seiten oder oben/unten. Oder möchten Sie die Vorschau gezoomt auf Vollbild. Ich verließ Kommentar mit mehr Informationen in
calcCamPrevDimensions()
.InformationsquelleAutor der Antwort Will Neithan
Hallo der getOptimalPreview (), das hier ist nicht für mich gearbeitet, also ich möchte zu teilen meine version:
InformationsquelleAutor der Antwort EstebanA
Nur zu diesem thread mehr komplett ich füge meine version der Antwort:
Was ich erreichen wollte:
Die Oberfläche Ansicht sollte nicht gedehnt werden, und es sollte sich auf den ganzen Bildschirm, Außerdem gab es nur ein Querformat-Modus in meinem app.
Lösung:
Die Lösung ist eine extrem kleine Erweiterung F1sher Lösung:
=> ein Erster Schritt ist die Integration F1sher Lösung.
=> Nun, es könnte ein Szenario entstehen, in F1sher Lösung, wenn die Oberfläche Ansicht nicht den gesamten Bildschirm erstreckt, ist Die Lösung, um die Oberfläche anzeigen, die größer als der Bildschirm Abmessungen, so dass es den gesamten Bildschirm erstreckt, für:
InformationsquelleAutor der Antwort Sarthak Mittal
Müssen Sie cameraView.getLayoutParams().Höhe und cameraView.getLayoutParams().Breite je nach Seitenverhältnis, die Sie wollen.
InformationsquelleAutor der Antwort user2919210
Dachte ich, was ist das problem - es ist mit Orientierung änderungen. Wenn Sie ändern der Kamera-Ausrichtung um 90 oder 270 Grad, als Sie brauchen, um swap Breite und Höhe der unterstützten Größen und alles wird ok sein.
Auch Oberfläche anzeigen sollen, liegen in einem frame-layout und Zentrum der Schwerkraft.
Hier ist ein Beispiel in C# (Xamarin):
Achten, dass die Kamera-Parameter sollte so eingestellt werden, original Größe (nicht getauscht), und surface view Größe sollte getauscht werden.
InformationsquelleAutor der Antwort Alexander Danilov
ich habe versucht, alle die Lösung, aber keiner von Ihnen arbeitet für mich. endlich löste ich mich selbst, und finde es ist eigentlich ganz einfach. es gibt zwei Punkte, die Sie benötigen, vorsichtig zu sein.
diese previewSize muss eine von der Kamera unterstützte Auflösung, die erhalten werden können, wie unten:
in der Regel eine der rawSupportedSize entspricht der Auflösung des Geräts.
Zweitens, legen Sie Ihre SurfaceView in ein FrameLayout, und legen Sie die Oberfläche layout-Breite und Höhe in surfaceChanged Methode wie oben
Ok, Dinge getan, hoffe das konnte dir helfen.
InformationsquelleAutor der Antwort SalutonMondo
Meine Anforderungen sind die Kamera-Vorschau werden müssen fullscreen und behalten das Seitenverhältnis bei.
Hesam und Yoosuf die Lösung war toll, aber ich sehe eine high-zoom-problem aus irgendeinem Grund.
Die Idee ist die gleiche, haben die Vorschau-container-center im übergeordneten und erhöhen Sie die Breite oder Höhe hängt von der Seitenverhältnisse, bis es den ganzen Bildschirm bedecken.
Eine Sache zu beachten ist die Größe der Vorschau ist in der Landschaft, da setzen wir die display-Ausrichtung.
Den container, fügen wir die SurfaceView anzeigen:
Fügen Sie die Vorschau, um es in den container, der mittig in der Eltern in Ihrer Aktivität.
Innerhalb der CameraPreview Klasse:
InformationsquelleAutor der Antwort Howard Lin
Gab ich die Berechnungen und einfach bekommen Sie die Größe der Ansicht wo ich will, die Kamera-Vorschau angezeigt und stellen Sie die Kamera Vorschau-Größe gleich (nur gespiegelt, Breite/Höhe, aufgrund der rotation) in meine custom SurfaceView Umsetzung:
InformationsquelleAutor der Antwort Martin Šuráb