【问题标题】:Calculate the correct with of UIImage using scale factor使用比例因子计算 UIImage 的正确值
【发布时间】:2021-03-23 19:13:06
【问题描述】:

我正在尝试使用指定选项创建基于位图的图形上下文。

这个想法是使用 scaleFactor 保存/重绘现有图像,因为 UIImageView 的内容模式为 aspectFit。

问题是使用比例因子后,保存图像的左边距有一个空白,我无法正确理解我做错了什么。

请查看附件,如果可能的话给我一些提示!

提前谢谢你!

和平与爱!

PS:附上方法和截图:

extension UIImageView {
  var mergedToImage: UIImage? {
    guard let originalImage = image else { return nil }
    let scaleFactor = CGFloat(max(originalImage.size.width / bounds.size.width,
                                  originalImage.size.height / bounds.size.height))
    
    let width = originalImage.size.width / scaleFactor
    let height = originalImage.size.height / scaleFactor
    
    let newSize = CGRect(x: 0, y: 0, width: width, height: height)
    UIGraphicsBeginImageContextWithOptions(newSize.size, false, 0.0)
    
    layer.render(in: UIGraphicsGetCurrentContext()!)
    
    let image = UIGraphicsGetImageFromCurrentImageContext()
    
    UIGraphicsEndImageContext()
    
    return image
  }
}

这里的工作版本: 已更新,感谢@Raja 提供的答案:

扩展 UIImageView { var mergeToImage: UIImage? {

    guard let originalImage = image else { return nil }
    
    UIGraphicsBeginImageContextWithOptions(originalImage.size, false, originalImage.scale)
    
    guard let currentContext = UIGraphicsGetCurrentContext() else {
        return nil
    }
    
    currentContext.scaleBy(
        x: originalImage.size.width / self.bounds.size.width,
        y: originalImage.size.height / self.bounds.size.height)
    
    layer.render(in: currentContext)
    
    let finalImage = UIGraphicsGetImageFromCurrentImageContext()
    
    UIGraphicsEndImageContext()
    return finalImage
}

}

   override func viewDidLoad() {
        super.viewDidLoad()
// Don't forget to add this:
        imageView.translatesAutoresizingMaskIntoConstraints = true
    }
    
    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        let mainImageFrame = AVMakeRect(aspectRatio: self.imageView.image?.size ?? .zero, insideRect: imageContainerView.frame)
        
        self.imageView.frame = CGRect(origin: CGPoint(x: (imageContainerView.frame.size.width / 2) - (mainImageFrame.width / 2), y: (imageContainerView.frame.size.height / 2) - (mainImageFrame.height / 2)), size: mainImageFrame.size)
    }

【问题讨论】:

  • 您想要与输入图像大小相同的输出。对吗?
  • 你可以试试UIGraphicsBeginImageContextWithOptions(newSize.size, false, 1.0),否则你的比例因子会是2。
  • @divanov42,感谢您的回复。两个选项都试过了,都不行,左边距还是有那个空白的地方。
  • @RajaKishan,是的,你是对的。
  • 你在图片上画过什么吗?我的意思是那里有任何掩蔽过程?

标签: ios swift uiimage scale


【解决方案1】:

在当前上下文中添加比例并在 UIGraphicsBeginImageContextWithOptions 中传递图像大小。

extension UIImageView {
    var mergedToImage: UIImage? {
        
        guard let originalImage = image else { return nil }
        
        UIGraphicsBeginImageContextWithOptions(originalImage.size, false, originalImage.scale)
        
        guard let currentContext = UIGraphicsGetCurrentContext() else {
            return nil
        }
        
        currentContext.scaleBy(
            x: originalImage.size.width / self.bounds.size.width,
            y: originalImage.size.height / self.bounds.size.height)
        
        layer.render(in: currentContext)
        
        let finalImage = UIGraphicsGetImageFromCurrentImageContext()
        
        UIGraphicsEndImageContext()
        return finalImage
    }
}

编辑 1:

根据提供的演示,直接设置图像视图。因此,首先,在一个 UIView 中添加图像视图,并根据图像大小设置图像视图框架。要查找图像显示帧,请使用 AVMakeRect。最后,您的视图控制器文件看起来像这样。

import UIKit
import AVFoundation

class ViewController: UIViewController {
    
    @IBOutlet private weak var eifellImageView: UIImageView!
    @IBOutlet private weak var imageContainerView: UIView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        eifellImageView.translatesAutoresizingMaskIntoConstraints = true
    }
    
    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        let mainImageFrame = AVMakeRect(aspectRatio: self.eifellImageView.image?.size ?? .zero, insideRect: imageContainerView.frame)
        
        self.eifellImageView.frame = CGRect(origin: CGPoint(x: (imageContainerView.frame.size.width / 2) - (mainImageFrame.width / 2), y: (imageContainerView.frame.size.height / 2) - (mainImageFrame.height / 2)), size: mainImageFrame.size)
    }
    
    @IBAction private func onShareAction(_ sender: UIButton) {
        let activityViewController = UIActivityViewController(activityItems: [self.eifellImageView.mergedToImage as Any], applicationActivities: nil)
        self.present(activityViewController, animated: true, completion: nil)
    }
}

【讨论】:

猜你喜欢
  • 2021-06-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-23
  • 2020-12-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多