ich auf einer Anwendung arbeite, die den Bildschirm in eine Bitmap erfassen muss zu übertragen. Ich versuche, die neue Android 5.0 android.media.projection APIs zu verwenden, um die Screen-Capture zu tun.Systemfehler die Ausgabe einer MediaProjection virtuellen Anzeige zu einem Imagereader erfassen
Der Workflow für diese API gipfelt in einem Aufruf von
mediaProjection.createVirtualDisplay("Test Screen", WIDTH, HEIGHT, DPI,
DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR, surface, null, null);
In meinem ersten Versuch in dieser capture ich die Oberfläche Objekt aus einem Surface bezogen. Dies funktioniert korrekt; Das Endergebnis ist ein winziges Duplikat der Anzeige, die auf dem Bildschirm gezeichnet wird (was zu einem
0) Ich dachte, das Feature fast abgeschlossen, aber I then discovered, dass SurfaceViews (vom Code Standpunkt) nicht lesbar sind; Sie können keine Bitmap von ihnen erhalten.
In nach anderen Lösungen suchen stieß ich auf this question, die ein sehr ähnliches Ziel zu mir hat, und in diesem Thread ist es suggested einen Imagereader anstelle einem Surface zu verwenden, um die Oberfläche, die Sie den createVirtualDisplay API-Aufruf übergeben zu beziehen.
Wenn ich jedoch meinen Code ändere, um einen ImageReader anstelle von SurfaceView zu verwenden, erhalte ich Laufzeit-Logcat-Fehler (keine Ausnahmen) und die Callback-Funktion für den ImageReader wird nie aufgerufen. Der createVirtualDisplay Aufruf gibt auch ein scheinbar gültiges VirtualDisplay Objekt. Hier
ist die logcat:
9230-9270/com.android.techrocket9.nanoid E/BufferQueueProducer﹕ [unnamed-9230-0] dequeueBuffer: createGraphicBuffer failed
9230-9246/com.android.techrocket9.nanoid E/BufferQueueProducer﹕ [unnamed-9230-0] dequeueBuffer: can't dequeue multiple buffers without setting the buffer count
9230-9246/com.android.techrocket9.nanoid E/BufferQueueProducer﹕ [unnamed-9230-0] dequeueBuffer: can't dequeue multiple buffers without setting the buffer count
9230-9246/com.android.techrocket9.nanoid E/BufferQueueProducer﹕ [unnamed-9230-0] dequeueBuffer: can't dequeue multiple buffers without setting the buffer count
9230-9246/com.android.techrocket9.nanoid E/BufferQueueProducer﹕ [unnamed-9230-0] dequeueBuffer: can't dequeue multiple buffers without setting the buffer count
Die zweite Zeile wiederholt ~ 100-mal, bevor es auftritt, stoppt.
Stepping auf dem Debugger durch Ich sehe, dass der erste Fehler während des createVirtualDisplay Anruf auftritt, und alle anderen passieren irgendwann nach der Ausführung kehrt zum Systemcode.
Die only meaningful result für diesen Fehler bezieht sich auf ein Problem in Kitkat, wo die API, die ich versuche zu konsumieren, nicht existiert. Trotzdem habe ich versucht, die fix suggested here (android:hardwareAccelerated="false"
im Manifest setzen). Dies hat das Verhalten der Anwendung nicht geändert.
Wie kann ich „die Pufferzählung“ oder auf andere Weise dieses Fehler umgehen und den Bildschirm als Bitmap erhalten?
P.S. Meine Entwicklungsplattform ist das Nexus 6.
Der vollständige Code-Block, wie gewünscht:
MediaProjection mediaProjection = mgr.getMediaProjection(resultCode, data);
ImageReader ir = ImageReader.newInstance(WIDTH, HEIGHT, ImageFormat.JPEG, 5);
VirtualDisplay v = mediaProjection.createVirtualDisplay("Test Screen", WIDTH, HEIGHT, getApplicationContext().getResources().getDisplayMetrics().densityDpi, DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR, ir.getSurface(), null, null);
Edit: In Bezug auf das Artefakt Problem, hier ist der Code Ich bin mit dem Bitmap aus dem Bild zu erhalten und zeigt es:
public void onImageAvailable(ImageReader reader) {
Image image = null;
ByteArrayOutputStream bos = null;
try {
image = reader.acquireLatestImage();
if (null == image){
return;
}
bos = new ByteArrayOutputStream();
final Image.Plane[] planes = image.getPlanes();
final ByteBuffer buffer = (ByteBuffer) planes[0].getBuffer().rewind();
final Bitmap bitmap = Bitmap.createBitmap(image.getWidth(), image.getHeight(), Bitmap.Config.ARGB_8888);
bitmap.copyPixelsFromBuffer(buffer);
//bitmap.compress(Bitmap.CompressFormat.WEBP, 50, bos);
runOnUiThread(new Runnable() {
public void run() {
iv.setImageBitmap(bitmap);
}
});
Ich bezweifle, dass ich persönlich dazu beitragen kann, aber es wäre nützlich, wenn Sie den Code zeigen, den Sie * verwenden (und Ihnen den Fehler gibt), anstatt den Code, den Sie verwendet haben benutzen. Darüber hinaus könntest du stattdessen [faddens Antwort darauf] (http://stackoverflow.com/a/26551760/115145) versuchen, wenn man bedenkt, dass er etwa 9 Jahre lang an Android gearbeitet hat :-). – CommonsWare
Hallo Ich habe das gleiche Problem, erhalten Sie irgendeine Lösung? – Charlesjean
@Charlesjean No. Fadden scheint einen alternativen Ansatz vorzuschlagen, der dieses Problem lösen könnte, aber seine Komplexität würde mehr Zeit in Anspruch nehmen als geplant für dieses Projekt. – Techrocket9