2012-06-25 13 views
7

Problem: Mam wielostronicowy obraz TIFF (wygenerowany za pomocą tiffutil), który zawiera ten sam obraz w wymiarze wielu pikseli od 256x128 px aż do 4096 x 2048 pikseli. Chcę wyświetlić ten obraz w formacie CALayer, aby system automatycznie wybierał najlepszą reprezentację obrazu w zależności od rozmiaru warstwy. W tej chwili warstwa zawsze korzysta z reprezentacji obrazu w rozdzielczości 256x128, niezależnie od jej wielkości.Automatyczne skalowanie wielu obrazów TIFF NSImage w kamerze

Oto, co zrobić: I załadować obraz z

NSImage *image = [NSImage imageNamed:@"map-multipage.tiff"]; 

Logowanie obiekt image potwierdza, że ​​zawiera wiele oświadczeń o różnych rozmiarach pikseli, ale wszystkie reprezentacje są tej samej wielkości w punktach (256x128). AFAIK w ten sposób firma Apple zaleca tworzenie obrazów o wielu rozdzielczościach.

NSLog(@"%@", image); 

<NSImage 0x100623060 Name=map-multipage Size={256, 128} Reps=(
    "NSBitmapImageRep 0x10064d330 Size={256, 128} ColorSpace=(not yet loaded) BPS=8 BPP=(not yet loaded) Pixels=256x128 Alpha=NO Planar=NO Format=(not yet loaded) CurrentBacking=nil (faulting) CGImageSource=0x10014fdb0", 
    "NSBitmapImageRep 0x10064e1b0 Size={256, 128} ColorSpace=(not yet loaded) BPS=8 BPP=(not yet loaded) Pixels=512x256 Alpha=NO Planar=NO Format=(not yet loaded) CurrentBacking=nil (faulting) CGImageSource=0x10014fdb0", 
    ... 
    "NSBitmapImageRep 0x100530bd0 Size={256, 128} ColorSpace=(not yet loaded) BPS=8 BPP=(not yet loaded) Pixels=4096x2048 Alpha=NO Planar=NO Format=(not yet loaded) CurrentBacking=nil (faulting) CGImageSource=0x10014fdb0" 
)> 

Następnie przypisać wystąpienie NSImage bezpośrednio do warstwy contents właściwości:

self.layerView.layer.contents = image; 

Jak już wspomniano, skutkiem jest to, że warstwę stosuje pierwszej reprezentacji (256x128 pikseli) w celu wyświetlania obrazu, bez względu na rozmiaru warstwy w punktach lub pikselach.

Po przypisaniu tego samego obrazu do NSImageView, działa zgodnie z oczekiwaniami. Widok obrazu w sposób przezroczysty wybiera najlepszą reprezentację obrazu w zależności od jego wielkości. Spodziewam się, że CALayer będzie działać w ten sam sposób, ale najwyraźniej tak nie jest. Czy ktoś może potwierdzić, że CALayer nie obsługuje tego automatycznego wyboru lub czy robię coś nie tak?

(Zauważ, że kwestia ta nie jest bezpośrednio związany z grafiką HiDPI/siatkówki. W rzeczywistości, jeśli ja przenieść warstwę na wyświetlaczu w trybie HiDPI, to nie czynią trochę ostrzejszy, wskazując, że teraz wykorzystuje drugą reprezentację bitmapy (512x256 px) do renderowania. sugeruje to, że automatyzm, aby wybrać wyższą rozdzielczość na HiDPI prac graficznych, natomiast podstawowym wybór najlepszej reprezentacji bitmapy zawiedzie.)

+0

Po prostu pomysł, spróbuj usunąć '.tiff' w' @ "map-multipage.tiff" '. Upewnij się również, że 'layerContentsRedrawPolicy' nie jest' Never'. A może warstwa 'contentsGravity' wpływa na to, jak jej zawartość jest aktualizowana? – Stream

+1

@Stream: wielkie dzięki za sugestie. Nie, usunięcie rozszerzenia pliku nie ma żadnego efektu, ani nie gra z 'layerContentsRedrawPolicy' lub' contentsGravity'. Po wczorajszej obserwacji sesji WWDC 2012 245, podejrzewam, że odpowiedź na moje pytanie brzmi: nie działa w ten sposób. Wygląda na to, że "treść" CALayera nie "nic" nie wie o rzeczywistym rozmiarze warstwy w punktach/pikselach, a zatem nie może wybrać reprezentacji bitmapy na podstawie tych informacji. –

+0

Ma sens! '- [Zawartość CALayer]' jest po prostu bitmapą, zbyt "głupim", aby wiedzieć cokolwiek o jej źródle. Jest to "CALayer", który polega na reprezentacji przez 'drawRect: inContext:'. Tak więc, gdy bezpośrednio ustawisz 'content', jego wymiar musi być oparty na bieżącym' - [NSImage size] '. – Stream

Odpowiedz

2

wydaje się metodą zestaw klas AppKit -[CALayer setContents:] wybiera reprezentację bitmapy rozmiar pasujący do obiektu -[contents size], jeśli obiekt jest to NSImage. Następnie wybrana bitmapa jest używana w takiej postaci, aż do ponownego wywołania -[CALayer setContents:].