2012-05-02 36 views
10

Trong ứng dụng iPad của tôi, tôi sẽ hiển thị bitmap ngoài màn hình và sau đó vẽ bitmap vào màn hình. (Điều này là bởi vì tôi muốn tái sử dụng mã bitmap hiện có.) Trên iPad 2, điều này hoạt động như một sự quyến rũ, nhưng trên iPad mới với màn hình Retina, vẽ bitmap là rất chậm, mặc dù độ phân giải của nó vẫn là tương tự.Vẽ hình ảnh với CoreGraphics trên iPad Retina chậm

Để vẽ bitmap, chúng tôi sử dụng các chức năng Quartz 2D thông thường: CGImageCreate với nhà cung cấp dữ liệu được tạo bởi CGDataProviderCreateWithData, định dạng RGBA 32 bit với kCGImageAlphaNoneSkipLast. Trong UIView hiển thị bitmap, trong drawRect:, chúng tôi sử dụng CGContextDrawImage để vẽ nó vào ngữ cảnh được trả về bởi UIGraphicsGetCurrentContext.

Lưu ý rằng tôi thậm chí không cố gắng vẽ ở độ phân giải kép: bây giờ tôi ổn với cùng độ phân giải như tôi đang sử dụng trên iPad 2. Có vẻ như CoreGraphics đang tăng gấp đôi pixel nội bộ và sau đó gửi đối với GPU, mặc dù CGImage mà tôi đang tạo ra sẽ tốt cho việc chuyển trực tiếp tới GPU. Ý tưởng nào?

Trả lời

15

Dường như CoreGraphics được nội tăng gấp đôi điểm ảnh, và sau đó gửi đến GPU,

Khá nhiều. Chính xác hơn (trong tinh thần ít nhất):

  1. UIKit làm cho một CGBitmapContext kích thước giới hạn của tầm nhìn của bạn, tính theo pixel thiết bị
  2. Nó làm cho bối cảnh bối cảnh hiện nay
  3. Bạn vẽ CGImage của bạn vào bối cảnh đó
  4. ... do CG có để rescale hình ảnh nguồn, và chạm vào tất cả các pixel điểm đến
  5. Sau khi bạn đã hoàn tất bản vẽ, UIKit làm cho một CGImage từ bối cảnh bitmap
  6. và gán nó cho nội dung của lớp xem.

CGImage mà tôi đang tạo sẽ ổn khi chuyển trực tiếp tới GPU.

Nếu bạn muốn điều đó xảy ra, bạn cần yêu cầu hệ thống thực hiện điều đó bằng cách cắt một số bước ở trên.

(Không có mối liên hệ giữa UIKit, CoreAnimation, và CoreGraphics mà cung cấp một "con đường nhanh" như bạn đang mong đợi.)

Cách đơn giản nhất sẽ là để thực hiện một UIImageView, và thiết lập của nó image đến một UIImage gói CGImageRef của bạn.

Hoặc đặt view.layer.contents thành CGImageRef của bạn. (Và hãy chắc chắn để không override -drawRect:, không gọi -setNeedsDisplay, và chắc chắn rằng contentModekhôngUIViewContentModeRedraw. Dễ chỉ cần sử dụng UIImageView.)

+0

Cảm ơn thông tin, mà có lẽ sẽ giúp rất nhiều. Chế độ xem là hoạt ảnh, vì vậy nó sẽ vẽ lại thường xuyên. Tôi nghĩ rằng do đó bằng cách sử dụng view.layer.nội dung có lẽ hiệu quả hơn việc gán một hình ảnh mới cho UIImageView, đúng không? –

+1

Đã thử và phương thức view.layer.contents hoạt động rực rỡ, cảm ơn bạn một lần nữa! –

+0

AFAIK hai phương pháp gần như bằng nhau về hiệu suất, nhưng như mọi khi: nếu nó quan trọng, hãy thử nó và xem. –

Các vấn đề liên quan