2012-06-25 12 views
7

Vấn đề: Tôi có một hình ảnh TIFF nhiều trang (được tạo bằng tiffutil) có chứa cùng một hình ảnh ở nhiều kích thước pixel từ 256x128 px đến 4096x2048 px. Tôi muốn hiển thị hình ảnh này trong một CALayer để hệ thống tự động chọn hình ảnh đại diện tốt nhất của hình ảnh tùy thuộc vào kích thước của lớp. Hiện tại, lớp luôn sử dụng hình ảnh 256x128 của hình ảnh, bất kể kích thước của nó là bao nhiêu.Tự động chia tỷ lệ của TIFF NSImage trong một CALayer

Dưới đây là những gì tôi làm: Tôi tải hình ảnh với

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

Logging đối tượng image xác nhận rằng nó chứa nhiều cơ quan đại diện có kích thước điểm ảnh khác nhau, nhưng tất cả các cơ quan đại diện có cùng kích thước trong điểm (256x128). AFAIK đây là cách Apple đề xuất các hình ảnh đa độ phân giải sẽ được xây dựng.

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" 
)> 

sau đó tôi giao dụ NSImage trực tiếp đến tài sản contents của lớp:

self.layerView.layer.contents = image; 

Như đã đề cập, kết quả là các lớp sử dụng các đại diện đầu tiên (256x128 px) để hiển thị hình ảnh, không phân biệt kích thước của lớp theo điểm hoặc pixel.

Khi tôi gán cùng một hình ảnh cho NSImageView, nó hoạt động như mong đợi. Xem hình ảnh minh bạch chọn hình ảnh đại diện tốt nhất tùy thuộc vào kích thước của nó. Tôi hy vọng rằng CALayer sẽ hoạt động theo cùng một cách nhưng rõ ràng đây không phải là trường hợp. Ai có thể xác nhận rằng CALayer không hỗ trợ lựa chọn tự động này hoặc tôi đang làm điều gì sai?

(Lưu ý rằng câu hỏi này không liên quan trực tiếp đến đồ họa HiDPI/Retina. Trên thực tế, nếu tôi di chuyển lớp đó sang màn hình ở chế độ HiDPI, nó sẽ hiển thị sắc nét hơn một chút. (512x256 px) để hiển thị. Điều này cho thấy rằng tự động chọn độ phân giải cao hơn trên màn hình HiDPI hoạt động trong khi lựa chọn cơ bản về biểu diễn bitmap tốt nhất không thành công.)

+0

Chỉ cần một ý tưởng, hãy thử xóa '.tiff' trong' @ "map-multipage.tiff" '. Ngoài ra, hãy đảm bảo rằng 'layerContentsRedrawPolicy' không phải là' Không bao giờ'. Hoặc có thể 'contentsGravity' của lớp ảnh hưởng đến cách nội dung của nó đang được cập nhật như thế nào? – Stream

+1

@Stream: cảm ơn rất nhiều vì những gợi ý. Không, việc xóa phần mở rộng của tệp không có hiệu lực, không chơi với 'layerContentsRedrawPolicy' hoặc' contentsGravity'. Sau khi xem WWDC 2012 phiên 245 đêm qua, tôi nghi ngờ câu trả lời cho câu hỏi của tôi là, nó không hoạt động theo cách đó. Có vẻ như 'nội dung' của 'CAL' không" biết "bất kỳ thứ gì về kích thước thực của lớp theo điểm/pixel và do đó không thể chọn biểu diễn bitmap dựa trên thông tin này. –

+0

Làm cho tinh thần! '- [Nội dung CALayer]' chỉ là một bitmap, quá “câm” để biết bất cứ điều gì về nguồn của nó. Nó là 'CALayer' dựa trên biểu diễn thông qua' drawRect: inContext: '. Vì vậy, khi bạn đặt 'nội dung' trực tiếp, thứ nguyên của nó phải dựa trên' - [kích thước ảnh NSImage] hiện tại '. – Stream

Trả lời

2

Có vẻ như phương pháp AppKit -[CALayer setContents:] chọn biểu diễn bitmap kích thước phù hợp với -[contents size] nếu đối tượng contentsNSImage. Sau đó, bitmap đã chọn được sử dụng cho đến khi -[CALayer setContents:] được gọi lại một lần nữa.