简体   繁体   English

如何从 UIImageView 获取显示的图像帧?

[英]How to get the displayed image frame from UIImageView?

I modify the UIImageView's contentMode property.我修改了 UIImageView 的 contentMode 属性。 So my image's frame is not equal to the frame of UIImageView.所以我的图像的框架不等于 UIImageView 的框架。 My problem is how to retrive the image's frame from UIImageView.我的问题是如何从 UIImageView 检索图像的框架。

As the following example, the orange rectangle is the UIImageView's border.如下例,橙色矩形是 UIImageView 的边框。 It is obviously that the frame of image is not the same as UIImageView.很明显,图像的框架与 UIImageView 不一样。

图1

If it's UIViewContentModeScaleAspectFit , it's something like this:如果它是UIViewContentModeScaleAspectFit ,它是这样的:

UIImageView *iv; // your image view
CGSize imageSize = iv.image.size;
CGFloat imageScale = fminf(CGRectGetWidth(iv.bounds)/imageSize.width, CGRectGetHeight(iv.bounds)/imageSize.height);
CGSize scaledImageSize = CGSizeMake(imageSize.width*imageScale, imageSize.height*imageScale);
CGRect imageFrame = CGRectMake(roundf(0.5f*(CGRectGetWidth(iv.bounds)-scaledImageSize.width)), roundf(0.5f*(CGRectGetHeight(iv.bounds)-scaledImageSize.height)), roundf(scaledImageSize.width), roundf(scaledImageSize.height));

In fact, it's built-in since iOS 4 (for UIViewContentModeScaleAspectFit ):事实上,它是从 iOS 4 开始内置的(对于UIViewContentModeScaleAspectFit ):

@import AVFoundation;

AVMakeRectWithAspectRatioInsideRect(imageView.image.size, imageView.bounds);

Since frame components may be not round numbers, consider wrapping the call by由于框架组件可能不是整数,请考虑通过以下方式包装调用

CGRectIntegral(…)

See http://nshipster.com/image-resizing/ for more tricks.有关更多技巧,请参阅http://nshipster.com/image-resizing/

Use this api from AVFoundation使用来自 AVFoundation 的这个 api

#import <AVFoundation/AVFoundation.h>

CGRect imageRect = 
    AVMakeRectWithAspectRatioInsideRect(imageView.image.size, imageView.bounds);
 if you want to calculate it yourself, use below code written by me.

func getImageFrameInImageView(imageView : UIImageView) -> CGRect {
    /*
    by 徐明刚, ericxu1983@163.com
    算法:
        设高宽比 r = h/w, 则:r(imageView) 缩写成r(v), r(image)缩写为r(i), 
        if r(i) > r(v), 则
        h(i) = h(v), 
        h(i) / w(i) = r(i) -> w(i) = h(i) / r(i)
        y = 0
        x = (w(v) / 2)  - (w(i) / 2)
    反之
    */

    let image = imageView.image!
    let wi = image.size.width
    let hi = image.size.height
    print("wi:\(wi), hi:\(hi)")

    let wv = imageView.frame.width
    let hv = imageView.frame.height
    print("wv:\(wv), hv:\(hv)")

    let ri = hi / wi
    let rv = hv / wv
    print("ri:\(ri), rv:\(rv)")

    var x, y, w, h: CGFloat

    if ri > rv {
        h = hv
        w = h / ri
        x = (wv / 2) - (w / 2)
        y = 0
    } else {
        w = wv
        h = w * ri
        x = 0
        y = (hv / 2) - (h / 2)
    }

    return CGRect(x: x, y: y, width: w, height: h)
}

To test if the function is right or not, I've used another view identifying the border of the image in UIImageView.为了测试该函数是否正确,我使用了另一个视图来标识 UIImageView 中的图像边框。

    let frameIdentifyBorderView = UIView(frame: imageFrameInImageView)
    frameIdentifyBorderView.layer.borderWidth = 3
    frameIdentifyBorderView.layer.borderColor = UIColor.blueColor().CGColor

    imageView.addSubview(frameIdentifyBorderView)

在此处输入图片说明

perfect!完美的!

The easiest way is to use AVMakeRectWithAspectRatioInsideRect .最简单的方法是使用AVMakeRectWithAspectRatioInsideRect Just import AVFoundation and you can get the rect in a single line of Code.只需导入 AVFoundation,您就可以在一行代码中获得矩形。 Swift 4. Be sure to import AVFoundation. Swift 4. 一定要导入 AVFoundation。

import UIKit
import AVFoundation

class ViewController: UIViewController {

    var imageView = UIImageView()
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        imageView.frame = self.view.bounds
        imageView.contentMode = .scaleAspectFit
        imageView.backgroundColor = .blue
        imageView.autoresizingMask = [.flexibleWidth,.flexibleHeight]
        self.view.addSubview(imageView)
    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)

        URLSession.shared.dataTask(with: URL(string: "https://images.pexels.com/photos/248797/pexels-photo-248797.jpeg?w=940&h=650&dpr=2&auto=compress&cs=tinysrgb")!) { (data, response, error) in
            guard let dt = data else{print("error");return}
            DispatchQueue.main.async {
                guard let image = UIImage(data: dt) else{print("error");return}
                self.imageView.image = image
                self.imageView.layoutIfNeeded()
                let realImageRect = AVMakeRect(aspectRatio: image.size, insideRect: self.imageView.bounds)


                //proof
                let view = UIView(frame: realImageRect)
                view.layer.borderColor = UIColor.green.cgColor
                view.layer.borderWidth = 3
                self.view.addSubview(view)
            }
        }.resume()
    }
}

Its very easy now现在很容易

import AVKit
    
let rect = AVMakeRect(aspectRatio: image.size, insideRect: containerView.bounds);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM