Jak bezpośrednio aktualizować piksele - za pomocą CGImage i bezpośredniego CGDataProvider
Rzeczywiste pytanie
Kilka odpowiedzi rozwiąże mój problem:
Czy mogę wymusićCGImage
przeładować swoje dane od bezpośredniego dostawcy danych (utworzonego za pomocąCGDataProviderCreateDirect
) lubićCGContextDrawImage
robi? A może w jakiś inny sposób mogę ustawić ustawienie self.layer.contents, aby to zrobić?Czy jestCGContext
konfiguracja lub sztuczka, której mogę użyć do renderowania obrazów 1024x768 z prędkością co najmniej 30 fpsCGContextDrawImage
.Czy ktoś był w stanie z powodzeniem korzystaćCVOpenGLESTextureCacheCreateTextureFromImage
dla aktualizacji bufora w czasie rzeczywistym z ich własnymi danymi tekstury? Myślę, że moim największym problemem jest stworzenieCVImageBuffer
jak skopiowałem inne właściwości z dokumentacji Jabłek dla tekstur. Gdyby ktoś miał więcej informacji na ten temat, byłby niesamowity.Wszelkie inne wskazówki dotyczące sposobu, w jaki mogę uzyskać obraz z pamięci na ekranie przy 30 fps.Tło (działki):
Pracuję nad projektem, w którym muszę zmodyfikować piksele danych obrazu NPOT w czasie rzeczywistym (minimum 30 fps) i narysować je na ekranie w iOS.
Moją pierwszą myślą było użycie OpenGL zglTexSubimage2D
aby zaktualizować, niestety zakończyło się to bardzo powoli (6 fps na iPadzie), ponieważ sterownik zamienia i konwertuje moje dane RGB na każdą klatkę do BGR. Więc wyślij to w BGR, a ty też, ale z jakiegoś powodu nie możesz zadzwonićglTexSubImage2D
zGL_BGR
domyśl. Wiem, że niektóre powolności wynikają z braku mocy 2 danych obrazu, ale moje wymagania dyktują to.
Więcej czytania doprowadziło mnie doCVOpenGLESTextureCacheCreateTextureFromImage
ale wszystkie przykłady dotyczą bezpośredniego wejścia kamery w celu uzyskaniaCVImageBufferRef
Próbowałem użyć dokumentacji (brak oficjalnych, ale tylko nagłówkowych komentarzy), aby mój własny CVImageBuffer tworzył moje dane obrazu, ale nie działałby z tym (bez błędów tylko pusta tekstura w debuggerze), co sprawia, że myślę, że Apple zbudował to specjalnie przetwarzać dane kamery w czasie rzeczywistym i nie zostało przetestowane poza tym obszarem, ale IDK.
W każdym razie po porzuceniu mojej godności przez zrzucenie OpenGL i przełączenie moich myśli na CoreGraphics zostałem poprowadzony do tego pytanianajszybszy sposób na narysowanie bufora ekranu w telefonie iPhone który zaleca używanie aCGImage
wspierane przezCGDataProviderCreateDirect
, który pozwala na powrót wskaźnika do danych obrazu, gdy CGImage tego potrzebuje, świetny, prawda? Cóż, wydaje się, że nie działa tak, jak reklamowano. Jeśli używamCGContextDrawImage
wtedy wszystko działa. Mogę modyfikować bufor pikseli, a każde losowanie żąda danych obrazu od mojego dostawcy danych, tak jak powinien, wywołując metodyCGDataProviderDirectCallbacks
(Note:
wydają się mieć wbudowaną optymalizację, która ignoruje zaktualizowany wskaźnik, jeśli ma ten sam adres, co poprzedni). CGContextDrawImage nie jest super szybki (około 18 klatek na sekundę), nawet przy wyłączonej interpolacji, która spowodowała wzrost z 6 fps. Dokumenty Apple mówią mi o użyciuself.layer.contents
będzie znacznie szybszy niżCGContextDrawImage
. Za pomocąself.layer.contents
działa dla pierwszego zadania, aleCGImage
nigdy nie żąda przeładowania od dostawcy danych, takiego jakCGContextDrawImage
robi, nawet gdy dzwonię[layer setNeedsDisplay]
. W zadanym przeze mnie pytaniu SO użytkownik pokazuje swoje rozwiązanie problemu, tworząc i niszcząc nowy obraz CGImage ze źródła danych w każdej klatce, beznadziejnie powolny proces (tak, spróbowałem), więc czas na prawdziwe pytanie.
Uwaga: Wyprofilowałem wszystkie te operacje i wiem, że problem naprawdę istniejeglTexSubImage
dla OpenGL iCGContextDrawImage
to naprawdę problem z CoreGraphics, więc nie ma odpowiedzi „przejdź do profilu”.
EDYTOWAĆ Kod źródłowy demonstrujący tę technikę można teraz znaleźć na stroniehttp://github.com/narpas/image-sequence-streaming