2011-02-10 9 views
5

Phát triển một đầu đọc PDF của iPad, chúng tôi quyết định chuẩn bị hình ảnh có độ phân giải cao để hiển thị các trang chuyên sâu (nhiều đường dẫn) và sử dụng chúng thay vì trang pdf để tránh các vấn đề về hiệu năng. Chúng tôi quyết định rằng 3*768 by 3*1024 là sự thỏa hiệp tốt giữa khả năng đọc và hiệu suất hiển thị kết quả là ~ 1,5 MB jpegs.Tại sao UIImageView lại tập trung nhiều hơn so với CGContextDrawImage

Tuy nhiên, chúng tôi đã thử nghiệm hai triển khai để hiển thị các trang hình ảnh. Một sử dụng lớp con CATiledLayer cũng chịu trách nhiệm xử lý các trang PDF "bình thường" (vẽ với CGContextDrawImage) và một trang khác sử dụng UIImageView. Cách thứ hai có lợi thế là hiển thị và thu phóng rất nhanh, nhưng việc sử dụng bộ nhớ thực sự tồi tệ - mất khoảng 30 MB trong bộ nhớ (phù hợp với kích thước bitmap của hình ảnh). Cách tiếp cận khác (CATiledLayer) cần nhiều thời gian hơn để hiển thị trang đầu tiên và cần thêm hai giây nữa để hiển thị lại sau khi phóng to (tương tự như trang pdf, nhưng nhanh hơn nhiều) nhưng không lấy nhiều bộ nhớ hơn mức cần hiển thị nhỏ hơn nhiều hình ảnh hoặc trang PDF.

Có ai biết điều gì đang diễn ra đằng sau hậu trường và nếu có thể kết hợp sử dụng bộ nhớ thấp CGContextDrawImage với hiệu suất cao là UIImageView bằng cách sử dụng khung thạch anh.

Trả lời

3

Không chắc nếu câu hỏi này vẫn còn có liên quan, nhưng nếu như vậy, có lẽ đây sẽ giúp:

Tôi đã chiến đấu trong trận chiến của màn hình hiệu quả các quan điểm lớn trong tiled image view của tôi là tốt. Có một loạt các bộ phận cơ bản cho vấn đề:

  • Một bình thường UIView, bao gồm UIImageView, dường như lúc nào cũng được hoàn toàn được hỗ trợ bởi bộ nhớ cho hình ảnh của mình. Ngay cả khi bạn triển khai phương thức drawRect:, dường như nó luôn vượt qua toàn bộ giới hạn của chế độ xem, không chỉ khu vực hiển thị trong chế độ xem cuộn. Như bạn đã khám phá, điều này nhanh chóng chiếm một bộ nhớ vì mỗi pixel mất 4 byte.
  • CATiledLayerkhông chỉ yêu cầu nội dung cho các ô hiển thị. Nó cũng loại bỏ các ô không còn nhìn thấy được nữa - đây là nơi tiết kiệm bộ nhớ đến. Tuy nhiên, nó có thông báo và bản vẽ trên một sợi nền, trong khi hoạt hình từ màu trắng sang nội dung. Dường như làm điều này thông qua một API riêng, tôi đã không tìm thấy cách để thực hiện lại chức năng của CATiledLayer làm lớp con của riêng tôi là CALayer, vì dường như không có cơ chế thông báo nào mà chúng ta có thể sử dụng như những con người.
  • Nếu bạn có nhiều chế độ xem trong chế độ xem cuộn, chúng sẽ nhận được các thông báo drawRect: một cách thích hợp khi chúng được phân trang. UIKit dường như đấu tranh với quá nhiều bài đánh giá dưới một lượt xem.

Đối với bạn, tôi có thể thấy một vài tùy chọn có thể:

  • Nó có thể là có thể cứu vãn thực hiện dựa trên CATiledLayer. fadeDuration mặc định là 0,25 giây, có thể quá dài nếu thời gian tải của bạn ngắn. Bạn có thể thả phần này xuống dưới một cái gì đó như 1.0/60.0, tức là một khung. Một điều không rõ ràng từ mô tả của bạn là liệu hình ảnh của bạn có bao gồm toàn bộ kích thước trang hay chỉ mỗi ô pixel 256x256 pixel. Giải mã toàn bộ JPEG lặp đi lặp lại cho mỗi lát sẽ chậm hơn nhiều so với việc giải mã các tệp khối riêng lẻ.
  • Nếu thời gian trễ thực hiện mọi thứ từ chuỗi CATiledLayer quá cao, bạn có thể tạo một loạt ô theo cách thủ công như UIImageView các bản xem trước thành UIView trống chính là chế độ xem phụ chính cho chế độ xem cuộn. Mỗi một trong số các bản xem trước này được gán hình ảnh lát gạch của riêng nó. Nếu bạn may mắn, UIKit sẽ đủ thông minh để loại bỏ nội dung của các khung nhìn này và tải lại các ảnh JPEG tương ứng theo yêu cầu.
  • Nếu UIImageViews không đủ thông minh hoặc bạn có quá nhiều lượt xem cho UIKit để đối phó, bạn có thể xây dựng chế độ xem của riêng bạn tải ảnh JPEG của chúng ở số drawRect:. Nếu nó vẫn còn quá khốc liệt, hãy thử với CALayers của riêng bạn, nó sẽ là sublayers của layer trống của khung nhìn duy nhất của bạn và tải lại hình ảnh của họ theo yêu cầu. Đây là những gì tôi cuối cùng đã đi cho xem hình ảnh lát gạch của tôi.

Điều đó phải bao gồm cuộn, nhưng nó vẫn có thể rất chậm nếu bạn cho phép người dùng thu nhỏ ngay (giảm thiểu). Trong trường hợp đó, tôi khuyên bạn nên lưu trữ các phiên bản có độ phân giải thấp phù hợp và tải/hiển thị những phiên bản đó ở các mức thu phóng ngoài cùng.

+0

Cảm ơn bạn rất nhiều vì câu trả lời chi tiết và khai sáng này. Mặc dù, dự án tôi thực sự yêu cầu điều này được thực hiện, tôi chắc chắn rằng lời giải thích của bạn sẽ hữu ích cho các vấn đề sắp tới và - nếu không - nó chỉ là tốt để biết. –