2010-07-26 37 views
14

Trong mã mẫu iPhone "PhotoScroller" từ WWDC 2010, chúng hiển thị cách thực hiện một mimmic khá tốt của ứng dụng Ảnh bằng cách cuộn, thu phóng và phân trang hình ảnh. Họ cũng xếp hình ảnh để hiển thị cách hiển thị hình ảnh có độ phân giải cao và duy trì hiệu suất tốt.Có thể gạch hình ảnh trong một UIScrollView mà không cần phải tự tạo tất cả các ô?

Tiling được triển khai trong mã mẫu bằng cách lấy trước các hình ảnh được chia tỷ lệ và cắt cho các độ phân giải khác nhau và đặt chúng vào lưới tạo thành toàn bộ hình ảnh.

Câu hỏi của tôi là: có cách nào để gạch hình ảnh mà không cần phải tự đi qua tất cả ảnh của bạn và tạo "ô xếp" không? Ứng dụng Ảnh có thể hiển thị hình ảnh lớn khi đang di chuyển như thế nào?

Sửa Đây là mã từ câu trả lời Deepa của dưới đây:

- (UIImage *)tileForScale:(float)scale row:(int)row col:(int)col size:(CGSize)tileSize image:(UIImage *)inImage 
{ 
CGRect subRect = CGRectMake(col*tileSize.width, row * tileSize.height, tileSize.width, tileSize.height); 
CGImageRef tiledImage = CGImageCreateWithImageInRect([inImage CGImage], subRect); 
UIImage *tileImage = [UIImage imageWithCGImage:tiledImage]; 
return tileImage; 
} 

Trả lời

12

Ở đây sẽ là đoạn mã cho thế hệ hình ảnh lát gạch:

Trong mã nguồn PhotoScroller thay tileForScale: row: col: với những điều sau:

inImage - Hình ảnh mà bạn muốn tạo gạch

- (UIImage *)tileForScale: (float)scale row: (int)row column: (int)col size: (CGSize)tileSize image: (UIImage*)inImage 
{ 
    CGRect subRect = CGRectMake(col*tileSize.width, row * tileSize.height, tileSize.width, tileSize.height); 
    CGImageRef tiledImage = CGImageCreateWithImageInRect([inImage CGImage], subRect); 
    UIImage *tileImage = [UIImage imageWithCGImage: tiledImage]; 
    return tileImage; 
} 

Kính trọng, Deepa

+0

Deepa, Cảm ơn bạn đã viết mã. Tôi đang nhận được một loạt các lỗi khi tôi cố gắng sử dụng nó. Bạn có nhớ chèn mã để nó định dạng chính xác không. Tôi có thể tạo ra một lỗi phiên mã đơn giản. Cảm ơn! – Jonah

+0

Chà, tôi hiểu rồi. Cám ơn rất nhiều. Đó là một chút chậm trên bay, nhưng nó làm những gì nó nghĩa vụ phải. Tôi sẽ dán mã trong câu hỏi của tôi ở trên. – Jonah

+0

@Jonah: Đây phải là câu trả lời được chấp nhận. – iwasrobbed

5

Tôi đã thấy điều này có thể được giúp đỡ: http://www.mikelin.ca/blog/2010/06/iphone-splitting-image-into-tiles-for-faster-loading-with-imagemagick/

Bạn chỉ cần chạy nó trong Terminal như một vỏ kịch bản trên máy Mac của bạn.

+0

Điều đó khá thú vị và có thể tiết kiệm rất nhiều thời gian. Nhưng, những gì tôi đang tìm kiếm là một cách để làm điều đó trong điện thoại. Ví dụ: ứng dụng Ảnh có thể nhanh chóng xoay/thu phóng ngay cả hình ảnh lớn. Tôi đoán là nó tự động vẽ hình ảnh. Nhưng, tôi có thể sai. – Jonah

3

Xin lỗi Jonah, nhưng tôi nghĩ rằng bạn không thể làm những gì bạn muốn.

Tôi đã triển khai một ứng dụng truyện tranh bằng cách sử dụng cùng một ví dụ làm tham chiếu và có cùng một nghi ngờ. Cuối cùng, tôi nhận ra rằng, ngay cả khi bạn có thể tải hình ảnh và cắt nó thành lát lần đầu tiên bạn sử dụng nó, bạn không nên. Có hai lý do cho điều đó:

  1. Bạn làm việc để tiết kiệm thời gian và phản hồi nhanh hơn. Tải và ốp lát cần có thời gian cho một hình ảnh lớn.
  2. Lý do trước đây đặc biệt quan trọng trong lần đầu tiên người dùng chạy ứng dụng.

Nếu hai lý do này không có ý nghĩa với bạn và bạn vẫn muốn làm điều đó, tôi sẽ sử dụng Quartz để tạo ô. Chức năng CGImage CGImageCreateWithImageInRect sẽ là điểm khởi đầu của tôi.

+0

Chắc chắn đồng ý về việc làm ốp lát bản thân trong chương trình ... bạn phải tải hình ảnh vào bộ nhớ mà đánh bại mục đích của ốp lát để bắt đầu với (để tiết kiệm bộ nhớ). Có thể tải hình ảnh lên máy chủ và yêu cầu cắt hình ảnh trước rồi tải xuống lại. – iwasrobbed

+0

Điều đó có ý nghĩa. Nhưng, câu hỏi của tôi là: Làm thế nào trên trái đất các ứng dụng hình ảnh làm điều đó? Ai đó có thể gửi cho bạn một bức ảnh 10MB và nó hoạt động hoàn hảo trong ứng dụng ảnh. Vì vậy, nếu không tiling trong ứng dụng, làm thế nào họ làm điều đó? – Jonah

+0

Như tôi đã đề cập, nó có thể được thực hiện với Quartz và tác động không quá lớn khi người dùng giả định rằng nó đang nhập ảnh, tôi nghĩ vậy. Đối với iTunes, bạn có thể đọc một thông báo có nội dung như "Tối ưu hóa ảnh cho iPod", mà tôi đoán là dành cho ốp lát –

2

Nhiều định dạng hình ảnh hỗ trợ giải mã dựa trên vùng. Thay vì tải toàn bộ hình ảnh vào bộ nhớ, giải nén toàn bộ và loại bỏ tất cả trừ khu vực quan tâm (ROI), bạn có thể tải và giải mã chỉ ROI, theo yêu cầu. Đối với hầu hết các phần, điều này giúp loại bỏ sự cần thiết phải tạo trước và lưu hình ảnh. Tôi đã không bao giờ làm việc với ImageMagick nhưng tôi sẽ ngạc nhiên nếu nó không thể làm điều đó. (Tôi đã thực hiện việc này bằng API Java Imaging Imaging (JAI), vốn sẽ không giúp bạn trên iPhone ...)

Tôi đã chơi với ví dụ PhotoScroller và cách nó hoạt động với gạch được tạo trước chỉ để minh họa ý tưởng đằng sau CATiledLayer và tạo một dự án tự hoạt động. Thật đơn giản để thay thế chiến lược tải hình ảnh xếp kề - chỉ cần viết lại phương thức TilingView tileForScale:row:col: để trả lại một ô UIImage từ một số nguồn khác, có thể là Quartz hoặc ImageMagick hay bất kỳ thứ gì.

+0

Nếu những gì bạn nói là chính xác, điều này có vẻ như một giải pháp tuyệt vời! Bạn có biết làm thế nào tôi sẽ đi về nhận được ROI mà không cần tải toàn bộ hình ảnh vào bộ nhớ với ImageMagick? Một cây trồng đơn giản, tương tự như những gì người này đang làm việc? Sẽ một cái gì đó như thế này tải toàn bộ hình ảnh vào bộ nhớ? http://www.mikelin.ca/blog/2010/06/iphone-splitting-image-into-tiles-for-faster-loading-with-imagemagick/ – Homeschooldev

3

Deepa của câu trả lời ở trên sẽ được tải toàn bộ hình ảnh vào bộ nhớ như một UIImage (biến đầu vào trong hàm của anh ta), đánh bại mục đích của ốp lát.

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