我问了一个类似于here的问题,得到了我接受的答案。我的新问题需要在图像视图上放置常规UIView
,使其他解决方案无法使用。所以,新问题......
UIImageView
上是否有方法告诉我其图像在其边界内的位置?说我有一辆汽车的照片,如下:
此图像为600x243,并且,在后轮应该的位置,有一个118,144,74,74(x,y,w,h)的孔。
我想将汽车图像放在UIImageView
中,根据布局大小是任意的,我希望看到整车的自然纵横比。因此,我将图片视图的内容模式设置为UIViewContentModeScaleAspectFit
,这非常有用。
例如,图像中的汽车是267x200:
我认为这样做可以将图像从w = 600缩放到w = 267,或者是267/600 = 0.445,并且(我认为)这意味着高度从200变为200 * 0.445 = 89 。而且我认为这个洞也被这个因素缩放了
但是我想在图像视图上方添加UIView
(作为兄弟姐妹),这是我感到困惑的地方。我知道图像大小,我知道imageView大小,我知道原始图像大小的孔框架。如何在缩放图像后获得孔框?
我尝试过这样的事情:
确定汽车图像在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?
确定洞的缩放框架:
CGFloat holeX = ratio*118;
CGFloat holeY = yPos + ratio*144;
CGFloat holeEdge = ratio*74;
CGRect holeRect = CGRectMake(holeX,holeY,holeEdge,holeEdge);
将holeRect转换为父视图的坐标系,为UIView兄弟创建框架。
[parentView convertRect:holeRect fromView:carImageView];
但必须有更好的方法。这些计算(如果它们是正确的)仅适用于比汽车更高的汽车图像视图。如果图像视图更宽,则代码需要不同。
我认为我可以为更广泛的观点制定逻辑,但它仍然可能是错误的。例如,yPos
计算。文档是否说,对于内容模式= AspectFit,图像在较大维度内居中?我没有看到任何地方。
请告诉我有更好的方法,或者,如果没有,是否证明我的想法适用于任意大小的图像,图像视图,孔?
感谢。
答案 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
坐标。我在下面的完整项目中添加了一个类别实现。
答案 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;
那是完整的,纠正过的矩形。