使用缩放将UIView放在UIImageView上

时间:2016-01-20 06:44:38

标签: ios objective-c uiimageview

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

UIImageView上是否有方法告诉我其图像在其边界内的位置?说我有一辆汽车的照片,如下:

car with missing wheel

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

我想将汽车图像放在UIImageView中,根据布局大小是任意的,我希望看到整车的自然纵横比。因此,我将图片视图的内容模式设置为UIViewContentModeScaleAspectFit,这非常有用。

例如,图像中的汽车是267x200:

enter image description here

我认为这样做可以将图像从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];
    
  4. 但必须有更好的方法。这些计算(如果它们是正确的)仅适用于比汽车更高的汽车图像视图。如果图像视图更宽,则代码需要不同。

    我认为我可以为更广泛的观点制定逻辑,但它仍然可能是错误的。例如,yPos计算。文档是否说,对于内容模式= AspectFit,图像在较大维度内居中?我没有看到任何地方。

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

    感谢。

2 个答案:

答案 0 :(得分:1)

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

好吧,结果AVFoundation有一些东西可以帮到你,但是如果你需要手动方式参考......

为了解决您的计算问题,只有在根据图像的宽度缩小图像时,我们只需添加一个快速三元运算符来比较图像视图和图像的比率...... / p>

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之后计算图像偏移量(文档未说明,但图像始终位于{的范围内{1}})。

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计算图像坐标中的矩形为UIView坐标。我在下面的完整项目中添加了一个类别实现。

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

答案 1 :(得分:1)

非常感谢@ originaluser2帮助我完成这项工作。事实证明AVFoundation库中有一个单线程:

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

imageRect将结束图像在imageView的坐标系中占据的矩形(因为我们传递了边界;传递帧将在父坐标系中求解)。 / p>

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

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;

那是完整的,纠正过的矩形。