2013-04-16 7 views
5

Próbuję radzić sobie z 16-bitów na kanał RGBA TIFF obrazów w języku C, nie mogłem znaleźć wiele informacji o 16-bitowych obrazów w specyfikacji.Obrazy TIFF: jak piksele obrazu 16 bit-RGBA są przeplatane?

W przypadku 8-bitowego obrazu RGBA na kanał, rozumiem, że piksel jest przechowywany jako uint32 i można go usunąć z przeplotu przez zgrupowanie 32 bitów na 4 grupy (R, G, B, A) z 8 bity. Wtedy do czynienia z 8 bitów na kanał RGBA obrazów, robię następujący (patrz także zamknięty kod źródłowy here):

  1. przechowywać dane obrazu jako zakładka UInt32 (używając TIFFReadRGBAImageOriented), które nazywam data_tiff
  2. I przeplot pikseli za pomocą następujących poleceń: (uint8) TIFFGetR(*data_tiff), (uint8) TIFFGetG(*data_tiff), (uint8) TIFFGetB(*data_tiff) & (uint8) TIFFGetA(*data_tiff)

W przypadku 16 bitów na kanał RGBA obrazu, może mi pan powiedzieć, jak czy mogę usunąć przeplot pikseli? czy mogę retreive danych obrazu jako zakładka uint64, wtedy będę mógł wykonać następujące czynności:

#define TIFF16GetR(abgr) ((abgr) & 0xffff) 
#define TIFF16GetG(abgr) (((abgr) >> 16) & 0xffff) 
#define TIFF16GetB(abgr) (((abgr) >> 32) & 0xffff) 
#define TIFF16GetA(abgr) (((abgr) >> 48) & 0xffff)` 
  1. czytam dane obrazu jako zakładka uint64
  2. I przeplotu pikseli za pomocą (uint16) TIFF16GetR(*data_tiff), (uint16) TIFF16GetG(*data_tiff), (uint16) TIFF16GetB(*data_tiff) & (uint16) TIFF16GetA(*data_tiff)

ale wydaje się, że dane nie są natywnie przechowywane w karcie uint64, więc zastanawiam się, w jaki sposób są przeplatane 16-bitów na kanał obrazów do UIN zakładka t32 pixel.

ja też mam trudności stojące czynienia z 16-bitów grayscaled obrazy w taki sam sposób (używając TIFFReadRGBAImageOriented aby uzyskać dane obrazu i próbują przekształcić każdy piksel w uint16)

Bardziej ogólnie, czy masz jakiś kawałek dokumentacji o 16-bitowych odcieniach szarości i kolorowych obrazach?

Dziękuję poważaniem

Rémy A.

+1

Co rozumiesz przez słowo "tab" powyżej? Nie mogę tego przetworzyć ... Może to być "stół"? – unwind

+0

Mam na myśli wskaźnik: uint32 * –

Odpowiedz

6

interfejs TIFFReadRGBAImage wysokim poziomie będzie zawsze odczytać obraz z dokładnością do 8 bitów na próbkę.

Aby odczytać obraz 16-bitowy na kanał bez utraty dokładności, można bezpośrednio użyć TIFFReadScanline i odczytać prawidłową ilość danych zgodnie z SamplesPerPixel i BitsPerSample. Ale działa to tylko wtedy, gdy obraz jest przechowywany w postaci pasków (nie płytek, które zostały wprowadzone w TIFF 6.0) i na każdym skompresowanym pasku musi znajdować się tylko jeden wiersz (jeśli obraz jest skompresowany).

Jeśli chcesz obsługiwać wszystkie rodzaju TIFF wihout użyciu TIFFReadRGBAImage potem trzeba wykryć formatu obrazu i obsłudze interfejs niskiego poziomu, takich jak TIFFReadEncodedStrip i TIFFReadEncodedTile.

Należy pamiętać, że specyfikacje TIFF są bardzo obszerne i elastyczne, a używanie tych niskopoziomowych interfejsów do obsługi każdego możliwego rodzaju obrazu nie będzie łatwym zadaniem, więc lepiej będzie, jeśli korzystasz z biblioteki o wyższym poziomie niż libtiff, jeśli mogą.

EDIT

Co masz na myśli w komentarzu jest pierwszą częścią specyfikacji TIFF 6.0 znanego jako Baseline TIFF

«Kiedy TIFF został wprowadzony, jego rozciągliwość sprowokowany kompatybilność Problemy z . Elastyczność w kodowaniu dała początek żartowi, że TIFF oznacza tysiące niekompatybilnych formatów plików. [9] Aby uniknąć tych problemów, każdy czytnik TIFF musiał czytać bazowy TIFF. TIFF Baseline nie zawiera warstw ani kompresji z JPEG lub LZW. Baseline TIFF jest formalnie znany jako TIFF 6.0, część 1: baseline TIFF »od Wikipedia

punkt odniesienia TIFF nie obsługuje głębokości nieco wyższa niż 8 bit, więc dlatego w specyfikacji Baseline TIFF, wartość BitsPerSample dla obrazu w skali szarości może wynosić tylko 4 lub 8, a dla obrazu RGB może wynosić tylko 8 bitów na kanał. Większa głębia bitowa jest obsługiwana jako rozszerzenie specyfikacji TIFF linii bazowej i nie jest wymagana, aby czytnik TIFF obsługiwał te linie.

kaflowe Obrazy jest również rozszerzenie specyfikacji Baseline gdzie StripOffsets, StripByteCounts i RowsPerStrip pola zastępuje TileWidth, TileLength, TileOffsets i TileByteCounts więc można odróżnić kafelki obraz z pozbawionego obrazu patrząc na istniejących pól przy użyciu TIFFGetField().

+0

Dziękuję za odpowiedź, mogłem przeczytać coś, co sugerujesz gdzieś w Internecie, które również mówi, że główne ograniczenie interfejsu zorientowanego na skanowanie, inne niż konieczność wcześniejszego zidentyfikowania istniejącego pliku jako posiadająca odpowiednią organizację, jest to, że losowy dostęp do poszczególnych linii skanowania może być zapewniony tylko wtedy, gdy dane nie są przechowywane w skompresowanym formacie lub gdy liczba wierszy w pasku danych obrazu jest ustawiona na jedną (RowsPerStrip to jeden). co oznacza, że ​​taki sposób radzenia sobie z obrazami o 16 bitach nie zadziała dla żadnego obrazu o 16 bitach, czy znasz inny sposób na zrobienie tego? –

+0

Tak, zredagowałem swoją odpowiedź, aby ograniczyć jawność podejścia do skanowania. – zakinster

+0

OK dziękuję za tę bardzo kompletną odpowiedź. Z przyjemnością korzystam z biblioteki wysokiego poziomu, ale im mniej wprowadzam zależności, tym lepiej ... –