2011-08-27 30 views
15

Giả sử tôi có hình ảnh (ví dụ: 1024 x 768 px) được hiển thị trong UIImageView (ví dụ: 300 x 300 px). Bây giờ, tôi muốn chuyển đổi một điểm từ hình ảnh, ví dụ: vị trí mũi của một người (x: 500, y: 600), đến điểm tương ứng trên UIImageView với nội dung của nóMode được tính đến.Chuyển đổi điểm từ hình ảnh sang điểm UIImageView, contentMode-aware

Nếu contentMode được cố định tại UIViewContentModeScaleToFill, việc chuyển đổi sẽ trở nên dễ dàng. Nhưng nếu đó là UIViewContentModeScaleAspectFit, mọi thứ trở nên phức tạp hơn.

Có cách nào thanh lịch để đạt được điều đó không? Tôi không thực sự muốn tính toán cho mỗi contentMode duy nhất (hơn 10, tôi nghĩ).

Cảm ơn!

Trả lời

29

Hôm nay, tôi đã có một số thời gian rảnh rỗi để cùng nhau giải pháp của tôi cho vấn đề này và xuất bản nó trên GitHub: UIImageView-GeometryConversion

Đó là một loại trên UIImageView cung cấp phương pháp để chuyển đổi các điểm và dễ phân biệt từ hình ảnh để xem tọa độ và tôn trọng tất cả 13 chế độ nội dung khác nhau.

Hy vọng bạn thích nó!

+0

Rất đẹp - Sẽ đẹp hơn nếu bạn cũng cung cấp một cách khác (từ phối hợp imageView đến tọa độ ảnh). – sarfata

+0

Bạn nói đúng, tôi sẽ sớm thêm nội dung này. – nubbel

+1

Đừng bận tâm, tôi đã thực hiện nó cho một số chế độ, tôi hoàn thành nó ngay bây giờ và sẽ gửi cho bạn một yêu cầu kéo về github sau ngày hôm nay. – sarfata

2

Không, không có cách tích hợp, công khai hoặc thanh lịch để thực hiện.

Bạn cần phải đảo ngược kỹ năng cho các chế độ nội dung bạn cần.

+0

Cảm ơn, tôi sẽ làm điều đó cho UIViewContentModeScaleToFill, UIViewContentModeAspectFit và UIViewContentModeAspectFill. Điều đó là đủ. – nubbel

+2

@nubbel - Khi hoàn tất, hãy công khai trên github hoặc theo cách khác, để người tiếp theo không phải nhảy qua cùng một vòng. – PeyloW

-1

Tại sao bạn không thể chỉ rescale tọa độ:

X (UIImageView) = (X (ảnh)/1024) * 300

Y (UIImageView) = (Y (Hình ảnh)/768) * 300

+0

Điều đó tốt cho UIViewContentModeScaleToFill, nhưng đối với các contentMode khác? – nubbel

+0

không hoạt động đối với UIContentModeScaleToFit vì lề sẽ xuất hiện và hình ảnh sẽ được căn giữa trong uiimageview – Vassily

10

đó là giải pháp quick'n'dirty tôi:

- (CGPoint)convertPoint:(CGPoint)sourcePoint fromContentSize:(CGSize)sourceSize { 
    CGPoint targetPoint = sourcePoint; 
    CGSize targetSize = self.bounds.size; 

    CGFloat ratioX = targetSize.width/sourceSize.width; 
    CGFloat ratioY = targetSize.height/sourceSize.height; 

    if (self.contentMode == UIViewContentModeScaleToFill) { 
     targetPoint.x *= ratioX; 
     targetPoint.y *= ratioY; 
    } 
    else if(self.contentMode == UIViewContentModeScaleAspectFit) { 
     CGFloat scale = MIN(ratioX, ratioY); 

     targetPoint.x *= scale; 
     targetPoint.y *= scale; 

     targetPoint.x += (self.frame.size.width - sourceSize.width * scale)/2.0f; 
     targetPoint.y += (self.frame.size.height - sourceSize.height * scale)/2.0f; 
    } 
    else if(self.contentMode == UIViewContentModeScaleAspectFill) { 
     CGFloat scale = MAX(ratioX, ratioY); 

     targetPoint.x *= scale; 
     targetPoint.y *= scale; 

     targetPoint.x += (self.frame.size.width - sourceSize.width * scale)/2.0f; 
     targetPoint.y += (self.frame.size.height - sourceSize.height * scale)/2.0f; 
    } 

    return targetPoint; 
} 

- (CGRect)convertRect:(CGRect)sourceRect fromContentSize:(CGSize)sourceSize { 
    CGRect targetRect = sourceRect; 
    CGSize targetSize = self.bounds.size; 

    CGFloat ratioX = targetSize.width/sourceSize.width; 
    CGFloat ratioY = targetSize.height/sourceSize.height; 

    if (self.contentMode == UIViewContentModeScaleToFill) { 
     targetRect.origin.x *= ratioX; 
     targetRect.origin.y *= ratioY; 

     targetRect.size.width *= ratioX; 
     targetRect.size.height *= ratioY; 
    } 
    else if(self.contentMode == UIViewContentModeScaleAspectFit) { 
     CGFloat scale = MIN(ratioX, ratioY); 

     targetRect.origin.x *= scale; 
     targetRect.origin.y *= scale; 

     targetRect.origin.x += (self.frame.size.width - sourceSize.width * scale)/2.0f; 
     targetRect.origin.y += (self.frame.size.height - sourceSize.height * scale)/2.0f; 

     targetRect.size.width *= scale; 
     targetRect.size.height *= scale; 
    } 
    else if(self.contentMode == UIViewContentModeScaleAspectFill) { 
     CGFloat scale = MAX(ratioX, ratioY); 

     targetRect.origin.x *= scale; 
     targetRect.origin.y *= scale; 

     targetRect.origin.x += (self.frame.size.width - sourceSize.width * scale)/2.0f; 
     targetRect.origin.y += (self.frame.size.height - sourceSize.height * scale)/2.0f; 

     targetRect.size.width *= scale; 
     targetRect.size.height *= scale; 
    } 

    return targetRect; 
} 

Khi nó refactored và tối ưu hóa, tôi sẽ xuất bản nó trên github và đăng liên kết xuống đây. Có lẽ cả đoạn mã đó cũng có thể hữu ích cho ai đó.

+1

Bạn đã từng xuất bản này chưa? –

+0

Tôi đã làm hôm nay, xem bài đăng khác của tôi. Tôi hy vọng bạn có thể tận dụng nó! – nubbel

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