2011-08-27 60 views
15

假设我有一个图像(例如1024 x 768像素),它显示在UIImageView(例如300 x 300像素)中。 现在,我想转换图像中的一个点,例如将人的鼻子(x:500,y:600)的位置与其内容模式考虑在内的UIImageView上的对应点相关联。将点从图像转换为UIImageView点,contentMode感知

如果contentMode固定在UIViewContentModeScaleToFill,转换将很容易。但是如果它是UIViewContentModeScaleAspectFit,事情会变得更加复杂。

有没有一种优雅的方式来实现这一目标?我真的不想计算每一个contentMode(超过10,我认为)。

谢谢!

回答

29

今天,我有一些空闲时间,我的解决方案放在一起,这个问题并发布在GitHub上:UIImageView-GeometryConversion

这是它提供了转换点和rects从图片查看方法上的UIImageView类别协调并遵守所有13种不同的内容模式。

希望你喜欢它!

+0

非常好 - 如果您还提供了其他方法(从imageView坐标到图像坐标),则会更好。 – sarfata

+0

你说得对,我马上加上。 – nubbel

+1

不要打扰,我已经完成了一些模式,我现在正在完成它,并会在今天晚些时候在github上向您发送拉请求。 – sarfata

2

不,没有内置的,公开的或优雅的方式来做到这一点。

您需要逆向设计自己需要的内容模式的功能。

+0

谢谢,我会为它做UIViewContentModeScaleToFill,UIViewContentModeAspectFit和UIViewContentModeAspectFill。这应该够了。 – nubbel

+2

@nubbel - 完成后请以github或其他方式公开,以便下一个人不必跳过相同的箍环。 – PeyloW

-1

为什么不能你只是重新调整坐标:

X(的UIImageView)=(X(图片)/ 1024)* 300

Y(的UIImageView)=(Y(图)/768)* 300

+0

这对UIViewContentModeScaleToFill有好处,但对于其他contentModes? – nubbel

+0

对于UIContentModeScaleToFit不起作用,因为边距将出现,并且图像将以uiimageview为中心 – Vassily

10

这是我quick'n'dirty解决方案:

- (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; 
} 

当它与重构优化后,我会在github上发布它,并将链接发布到这里。 也许这个片段可能对某人有帮助。

+1

您是否曾发布过? –

+0

今天我做了,看到我的其他帖子。我希望你能利用它! – nubbel