【问题标题】:Position a UIView over a UIImageView with scaling通过缩放将 UIView 定位在 UIImageView 上
【发布时间】:2016-04-25 21:28:38
【问题描述】:

我问了一个与here 类似的问题,并得到了我接受的答案。我的新问题需要将常规的UIView 放置在图像视图上,从而使其他解决方案无法使用。所以,新的问题......

UIImageView 上是否有一种方法可以告诉我其图像在其边界内的位置?假设我有一张汽车的图像,如下所示:

这张图片是 600x243,并且,后轮应该在的位置,有一个 118,144,74,74 (x,y,w,h) 的孔。

我想将汽车图像放置在UIImageView 中,其大小基于布局是任意的,并且我想以自然的纵横比查看整辆车。所以我将图像视图的内容模式设置为UIViewContentModeScaleAspectFit,效果很好。

例如,这是 267x200 的 imageView 中的汽车:

我认为这样做会将图像从 w=600 缩放到 w=267,或者,缩放系数为 267/600=0.445,并且(我认为)这意味着高度从 200 变为 200*0.445=89 .而且我认为这个洞也确实被那个因素放大了

但我想在图像视图上方添加一个UIView(作为兄弟),这就是我感到困惑的地方。我知道图像大小,我知道 imageView 大小,并且我知道原始图像大小方面的孔框。图片缩放后如何得到孔框?

我尝试过这样的事情:

  1. 确定汽车图像在其UIImageView 中的位置。是这样的:

    float ratio=carImage.width/carImageView.frame.size.width;  // 0.445
    CGFloat yPos=(carImageView.frame.size.height-carImage.height)/2;  // there should be a method for this?
    
  2. 确定孔的缩放框架:

    CGFloat holeX = ratio*118;
    CGFloat holeY = yPos + ratio*144;
    CGFloat holeEdge = ratio*74;
    CGRect holeRect = CGRectMake(holeX,holeY,holeEdge,holeEdge);
    
  3. 将holeRect转换为父视图的坐标系,为UIView兄弟创建框架。

    [parentView convertRect:holeRect fromView:carImageView];
    

但是必须有更好的方法。这些计算(如果它们是正确的)仅适用于比汽车更高的汽车图像视图。如果图像视图更宽,代码需要不同。

我想我可以为更广阔的视野找出逻辑,但它仍然可能是错误的。比如那个yPos计算。文档是否说,对于内容模式 = AspectFit,图像在较大尺寸内居中?我没看到那个地方。

请告诉我有更好的方法,或者,如果没有,是否证明我的想法适用于任意大小的图像、图像视图、孔?

谢谢。

【问题讨论】:

    标签: ios objective-c uiimageview


    【解决方案1】:

    就像我在你上一个问题上所说的那样,UIKit 没有什么方便的东西可以为你计算这个,所以你必须自己做。

    好吧,原来AVFoundation 可以帮助您,但如果您需要手动方式作为参考...


    为了解决仅在图像根据其宽度按比例缩小时计算的问题,让我们添加一个快速三元运算符来比较图像视图和图像的比率...

    CGSize imageViewSize = imageView.frame.size;
    
    CGFloat imgRatio = imageSize.width/imageSize.height; // The ratio of the image before scaling.
    CGFloat imgViewRatio = imageViewSize.width/imageViewSize.height; // The ratio of the image view
    
    CGFloat ratio = (imgRatio > imgViewRatio)? imageViewSize.width/imageSize.width:imageViewSize.height/imageSize.height; // The ratio of the image before scaling to after scaling.
    

    这将允许在同一图像视图中按比例缩小横向和纵向图像。

    接下来,您要在应用了UIViewContentModeScaleAspectFit 之后计算图像位于图像视图中的偏移量(文档没有说明,但图像始终在UIImageView 的范围内居中)。

    CGFloat yOffset = (imageViewSize.height-(imageSize.height*ratio))*0.5; // The y-offset of the image on-screen (as it gets centered)
    CGFloat xOffset = (imageViewSize.width-(imageSize.width*ratio))*0.5; // The x-offset of the image on-screen (as it gets centered)
    

    接下来,您要使用您在问题中定义的值计算子图像的原点和大小(您要插入孔中的 UIView)。

    CGPoint subImgOrigin = {117.0*ratio, 142.0*ratio}; // The origin of the sub-image (relative to the origin of the image)
    CGSize subImageSize = {74.0*ratio, 74.0*ratio}; // The size of the sub-image
    

    最后,您希望将这些值传递到您的UIView(或UIImageView,如果您想将此应用于您的原始问题)

    // Your wheel view
    UIView* wheel = [[UIView alloc] initWithFrame:(CGRect){xOffset+subImgOrigin.x, yOffset+subImgOrigin.y, subImageSize.width, subImageSize.height}];
    wheel.backgroundColor = [UIColor redColor];
    [self.view addSubview:wheel];
    

    走得更远……

    您可以将其实现为UIImageView 的类别,允许您从任何UIImageView 将图像坐标中的矩形计算为UIView 坐标。我在下面的完整项目中添加了一个类别实现。


    完整项目:https://github.com/hamishknight/Car-Sub-Image

    【讨论】:

    • 非常感谢。事实证明,AVFoundation 中有 SDK 帮助。有点晦涩。
    【解决方案2】:

    非常感谢 @originaluser2 帮助我解决这个问题。事实证明,AVFoundation 库中有一个可用的单行代码:

    // given an imageView and an image
    CGRect imageRect = AVMakeRectWithAspectRatioInsideRect(image.size, imageView.bounds);
    

    imageRect 将作为图像在 imageView 坐标系中占据的矩形结束(因为我们通过了边界;通过框架将在父坐标系中解决)。

    对于我的问题,我现在可以根据以下方式缩放孔矩形:

    CGFloat scaleX = image.size.width / imageView.bounds.size.width;
    CGFloat scaleY = image.size.height / imageView.bounds.size.height;
    

    既然我有了imageRect的原点,那么难的部分就完成了,直接加吧:

    CGFloat scaledOriginX = holeX*scaleX + imageRect.origin.x;
    CGFloat scaledOriginY = holeY*scaleY + imageRect.origin.y;
    

    当然,还可以缩放洞的宽度和高度:

    CGFloat scaledWidth = holeWidth*scaleX;
    CGFloat scaledHeight = holeHeight*scaleY;
    

    这就是完整的、更正的矩形。

    【讨论】:

    • 哇,这确实是超级晦涩... AVUtilities.h 中的唯一功能。很有趣!
    • 这里的孔和孔宽是什么?
    • @KishoreKumar - 它们在问题中定义:我想要缩放以匹配图像自动缩放的图像中孔的 x 位置和宽度
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-08-16
    • 2019-09-02
    • 2010-12-07
    • 1970-01-01
    • 2013-08-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多