Android: how to display Kamera-Vorschau mit callback?
Was ich tun muss, ist ganz einfach, ich will manuell Vorschau von der Kamera mit Kamera-Rückruf und ich wollen mindestens 15 fps auf einem echten Gerät. Ich Brauch nicht mal die Farben, ich brauche nur ein Vorschau-Bild in Graustufen.
Bilder aus der Kamera im YUV-format, und Sie haben, um es zu verarbeiten, irgendwie, das ist die wichtigste performance-problem. Ich bin mit API 8.
In allen Fällen bin ich mit Kamera.setPreviewCallbackWithBuffer(), dass ist schneller als die Kamera.setPreviewCallback(). Es scheint, dass ich kann nicht über 24 fps hier, wenn ich mich nicht Anzeige der Vorschau. Es ist also nicht das problem.
Habe ich versucht diese Lösungen:
1. Display-Kamera-Vorschau auf einem SurfaceView als Bitmap. Es funktioniert, aber die Leistung wird über 6fps.
baos = new ByteOutputStream();
yuvimage=new YuvImage(cameraFrame, ImageFormat.NV21, prevX, prevY, null);
yuvimage.compressToJpeg(new Rect(0, 0, prevX, prevY), 80, baos);
jdata = baos.toByteArray();
bmp = BitmapFactory.decodeByteArray(jdata, 0, jdata.length); //Convert to Bitmap, this is the main issue, it takes a lot of time
canvas.drawBitmap(bmp , 0, 0, paint);
2. Display-Kamera-Vorschau auf eine GLSurfaceView als textur. Hier war ich der Anzeige nur die Luminanz-Daten (Graustufen-Bild), die ist ganz einfach, es erfordert nur eine arraycopy() auf jedem Bild. Ich kann über 12fps, aber ich muß auch anwenden bestimmter Filter auf das Album und es scheint, dass es nicht getan werden kann schnell in OpenGL ES 1. So kann ich nicht diese Lösung verwenden. Einige details dieser in eine andere Frage.
3. Display-Kamera-Vorschau auf eine (GL)SurfaceView mit NDK zum verarbeiten der YUV-Daten. Ich finde eine Lösung hier , verwendet einige C-Funktion und NDK. Aber ich schaffte es nicht, es zu benutzen, hier einige weitere details. Aber wie auch immer, diese Lösung wird getan, um zurückzukehren, ByteBuffer, um es anzuzeigen als textur in OpenGL und es wird nicht schneller sein als die vorherigen Versuch. Also ich würde ändern müssen, um es zurück int [] - array, das gezeichnet werden kann, mit Leinwand.drawBitmap(), aber ich verstehe nicht, C genug, dies zu tun.
So, gibt es eine andere Möglichkeit, die ich bin fehlt oder einige Verbesserungen, um die versuche habe ich schon versucht?
InformationsquelleAutor der Frage Jaa-c | 2011-12-02
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ich bin auf genau das gleiche Problem, aber habe nicht ganz so weit wie du haben.
Haben Sie als zeichnen der Pixel direkt auf die Leinwand ohne Codierung in JPEG als erstes? Innerhalb der OpenCV-kit http://sourceforge.net/projects/opencvlibrary/files/opencv-android/2.3.1/OpenCV-2.3.1-android-bin.tar.bz2/download (die ja eigentlich nicht verwenden opencv; Mach dir keine sorgen), es gibt ein Projekt mit dem Namen tutorial-0-androidcamera, das veranschaulicht, die Umwandlung YUV-Pixel-RGB-und dann schreiben Sie diese direkt auf ein bitmap.
Der entsprechende code ist im wesentlichen:
Natürlich müsste man es anpassen, um Ihre Bedürfnisse zu erfüllen (ex. nicht die Zuweisung rgba jeden Rahmen), aber es könnte der Anfang sein. Ich würde gerne, um zu sehen, ob es für Sie arbeitet oder nicht-ich bin immer noch kämpfen, Probleme, die orthogonal zu verkaufen im moment.
InformationsquelleAutor der Antwort Michael
Ich denke, Michael ist auf dem richtigen Weg. Zunächst können Sie versuchen, diese Methode zum konvertieren von RGB nach Graustufen. Klar, es tut fast das gleiche wie seine,aber ein wenig mehr kurz und bündig, was Sie wollen.
}
Zweite, erstellen Sie nicht eine Tonne Arbeit für den garbage collector. Ihre bitmaps und arrays sind dabei, eine Feste Größe. Erstellen Sie einmal, nicht in onFramePreview.
Tun, werden Sie am Ende mit etwas, das aussieht wie dieses:
Und dann die Leinwand, wo Sie wollen, es sieht wie folgt aus:
Dieses Beispiel zeigt eine beschnitten und verzerrt Auswahl der Kamera-Vorschau in Echtzeit, aber Sie bekommen die Idee. Es läuft bei hohen FPS auf einem Nexus S in Graustufen und sollte für deine Bedürfnisse.
InformationsquelleAutor der Antwort sarwar
Ist es nicht dies, was Sie wollen? Verwenden Sie einfach eine SurfaceView in layout, dann irgendwo im init, wie
onResume()
:Es nur sendet die frames gerade zu der Ansicht, so schnell, wie Sie ankommen.
Wenn Sie möchten, Graustufen-ändern Sie die Parameter der Kamera mit
setColorEffect("mono")
.InformationsquelleAutor der Antwort Sean Owen
Sehr einfache und einfache Effekte, es ist
Ich herausgefunden, dass diese Auswirkungen UNTERSCHIEDLICH, je nach Gerät.
Zum Beispiel, auf meinem Handy (galaxy s II) er sieht ein bisschen wie ein comic-Effekt, denn im Gegensatz zu den galaxy s 1 es ist 'nur' ein blauer Schatten.
Es ist pro: Es arbeitet als live-Vorschau.
Schaute ich mich um einige andere Kamera-apps und offensichtlich auch angesichts dieses Problems.
Also, was haben Sie zu tun?
Sie erfassen die Standard-Kamera-Bild anwenden eines filters auf die bitmap-Daten, und zeigen Sie dieses Bild in eine einfach Bildansicht. Es ist sicher nicht so cool wie live-Vorschau, aber Sie werden nicht immer Probleme.
InformationsquelleAutor der Antwort poitroae
Ich glaube, ich lese in einem blogdass die Graustufen-Daten ist in den ersten x*y bytes. Yuv darstellen sollte, Leuchtdichte, also die Daten sind da, obwohl es nicht eine perfekte Graustufen. Es ist toll für die relative Helligkeit, aber nicht in Graustufen, wie jede Farbe ist nicht so hell wie jeder andere in rgb. Grün ist in der Regel gegeben ein stärkeres Gewicht in der Leuchtkraft Konvertierungen. Hoffe, das hilft!
InformationsquelleAutor der Antwort rickstockham
Gibt es einen speziellen Grund, dass Sie gezwungen sind, zu verwenden GLES 1.0 ?
Weil wenn nicht, sehen die akzeptierte Antwort hier:
Android SDK: Get raw Vorschau-Bild der Kamera, ohne es anzuzeigen
Generell erwähnt die Kamera verwenden.setPreviewTexture() in Kombination mit GLES 2.0.
In der GLES 2.0 wiedergegeben werden können, eine full-screen-quad-alle über der Bildschirm, und erstellen Sie was auch immer Effekt, den Sie möchten.
Es ist wahrscheinlich der Schnellste Weg möglich.
InformationsquelleAutor der Antwort ZeDuS