Konvertieren eines kCVPixelFormatType_420YpCbCr8BiPlanarFullRange-Puffers zu UIImage in iOS

8

Ich habe versucht, dies im ursprünglichen Thread zu beantworten, aber SO würde mich nicht lassen. Hoffentlich kann jemand mit mehr Autorität das in die ursprüngliche Frage einfließen lassen.

OK, hier ist eine vollständigere Antwort. Richte zuerst das Capture ein:

%Vor%

OK jetzt die Implementierung für den Delegaten / Callback:

%Vor%

und schließlich ist hier die Methode, um von YUV zu einem UIImage

zu konvertieren %Vor%

Sie müssen auch #import "Endian.h"

Beachten Sie, dass der Aufruf von CGBitmapContextCreate wesentlich komplizierter ist als erwartet. Ich bin nicht sehr versiert auf Videoverarbeitung überhaupt, aber dieser Anruf hat mich für eine Weile ratlos. Dann, als es endlich funktionierte, war es wie Magie.

    
MichaelG 02.11.2012, 18:32
quelle

1 Antwort

2

Hintergrundinfo: @ Michaelgs Version greift nur auf den y-Puffer zu, so dass Sie nur Luminanz und nicht Farbe erhalten. Es hat auch einen Buffer-Overrun-Bug, wenn die Tonhöhe in den Puffern und die Anzahl der Pixel nicht übereinstimmen (Füll-Bytes am Ende einer Zeile, aus welchem ​​Grund auch immer). Der Hintergrund zu dem, was hier passiert, ist, dass dies ein planares Bildformat ist, das ein Byte pro Pixel für die Luminanz und 2 Bytes pro 4 Pixel für die Farbinformation zuweist. Diese werden nicht ständig im Speicher gespeichert, sondern als "Ebenen" gespeichert, wobei die Y- oder Luminanzebene einen eigenen Speicherblock hat und die CbCr- oder Farbebene auch einen eigenen Speicherblock hat. Die CbCr-Ebene besteht aus 1/4 der Anzahl der Abtastungen (halbe Höhe und Breite) der Y-Ebene und jedes Pixel in der CbCr-Ebene entspricht einem 2x2-Block in der Y-Ebene. Hoffentlich hilft dieser Hintergrund.

edit: Sowohl seine Version als auch meine alte Version hatten das Potenzial, Puffer zu überschreiben und würden nicht funktionieren, wenn die Zeilen im Bildpuffer am Ende jeder Zeile Füllbytes hätten. Außerdem wurde mein cbcr-Ebenenpuffer nicht mit dem korrekten Offset erstellt. Um dies richtig zu machen, sollten Sie immer die Kern-Video-Funktionen wie CVPixelBufferGetWidthOfPlane und CVPixelBufferGetBaseAddressOfPlane verwenden. Dies stellt sicher, dass Sie den Puffer richtig interpretieren, und es wird funktionieren, unabhängig davon, ob der Puffer einen Header hat und ob Sie die Zeigermathematik vermasseln. Sie sollten die Zeilengrößen von Apples Funktionen und die Pufferbasisadresse auch von ihren Funktionen verwenden. Diese sind dokumentiert unter: Ссылка Beachten Sie, dass während dieser Version hier nutzt einige der Funktionen von Apple und einige Verwendung der Kopfzeile ist es am besten, nur Apples Funktionen zu verwenden. Ich kann dieses in der Zukunft aktualisieren, um die Überschrift überhaupt nicht zu benutzen.

Dies wird einen kcvpixelformattype_420ypcbcr8biplanarfullrange Pufferspeicher in einen UIImage konvertieren, den Sie dann verwenden können.

Richten Sie zuerst das Capture ein:

%Vor%

OK jetzt die Implementierung für den Delegaten / Callback:

%Vor%

und schließlich ist hier die Methode, um von YUV zu einem UIImage

zu konvertieren %Vor%

Sie müssen auch #import "Endian.h" und die Definition #define clamp(a) (a>255?255:(a<0?0:a));

angeben

Beachten Sie, dass der Aufruf von CGBitmapContextCreate wesentlich komplizierter ist als erwartet. Ich bin nicht sehr versiert auf Videoverarbeitung überhaupt, aber dieser Anruf hat mich für eine Weile ratlos. Dann, als es endlich funktionierte, war es wie Magie.

    
meursault334 28.05.2015 05:18
quelle