如何合并两个UIImages并保持纵横比和大小?

6

代码已经添加到Github,以便让您了解实际问题。


这是层次结构:

-- ViewController.View P [width: 375, height: 667]
---- UIImageView A       [width: 375, height: 667] Name: imgBackground
                         [A is holding an image of size(1287,1662)]
---- UIImageView B       [width: 100, height: 100] Name: imgForeground
                         [B is holding an image of size(2400,982)]

我正在尝试将A与B合并,但结果被拉伸了。

这是合并代码:

func mixImagesWith(frontImage:UIImage?, backgroundImage: UIImage?, atPoint point:CGPoint, ofSize signatureSize:CGSize) -> UIImage {
    let size = self.imgBackground.frame.size
    UIGraphicsBeginImageContextWithOptions(size, false, UIScreen.main.scale)
    backgroundImage?.draw(in: CGRect.init(x: 0, y: 0, width: size.width, height: size.height))
    frontImage?.draw(in: CGRect.init(x: point.x, y: point.y, width: signatureSize.width, height: signatureSize.height))
    let newImage:UIImage = UIGraphicsGetImageFromCurrentImageContext()!
    UIGraphicsEndImageContext()
    return newImage
}

注意:
  • .contentMode = .scaleAspectFit
  • 代码可以工作但结果被拉伸了。
  • 请看代码中的这一行,let size = self.imgBackground.frame.size - 我需要更改此行以解决问题。找到子视图相对于UIImage大小的原点

以下是用于理解问题的屏幕截图:

enter image description here

我应该怎么做才能正确使用合并函数?

2个回答

2
尝试下面的代码,它对我有效,希望对你也有效。
func addWaterMarkToImage(img:UIImage, sizeWaterMark:CGRect, waterMarkImage:UIImage, completion : ((UIImage)->())?){
     handler = completion
    let img2:UIImage = waterMarkImage
    let rect = CGRect(x: 0, y: 0, width: img.size.width, height: img.size.height)
    UIGraphicsBeginImageContext(img.size)
    img.draw(in: rect)
    let frameAspect:CGRect = getAspectFitFrame(sizeImgView: sizeWaterMark.size, sizeImage: waterMarkImage.size)
    let frameOrig:CGRect = CGRect(x: sizeWaterMark.origin.x+frameAspect.origin.x, y: sizeWaterMark.origin.y+frameAspect.origin.y, width: frameAspect.size.width, height: frameAspect.size.height)
    img2.draw(in: frameOrig, blendMode: .normal, alpha: 1)

    let result = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()

    if handler != nil {
        handler!(result!)
    }
}
//MARK - Get Aspect Fit frame of UIImage
func getAspectFitFrame(sizeImgView:CGSize, sizeImage:CGSize) -> CGRect{

    let imageSize:CGSize  = sizeImage
    let viewSize:CGSize = sizeImgView

    let hfactor : CGFloat = imageSize.width/viewSize.width
    let vfactor : CGFloat = imageSize.height/viewSize.height

    let factor : CGFloat = max(hfactor, vfactor)

    // Divide the size by the greater of the vertical or horizontal shrinkage factor
    let newWidth : CGFloat = imageSize.width / factor
    let newHeight : CGFloat = imageSize.height / factor

    var x:CGFloat = 0.0
    var y:CGFloat = 0.0
    if newWidth > newHeight{
        y = (sizeImgView.height - newHeight)/2
    }
    if newHeight > newWidth{
        x = (sizeImgView.width - newWidth)/2
    }
    let newRect:CGRect = CGRect(x: x, y: y, width: newWidth, height: newHeight)

    return newRect

}

2
你的代码有两个bug:
  1. You should also calculate aspect for document image to fit it into UIImageView. In mergeImages() replace:

    img.draw(in: CGRect(x: 0, y: 0, width: size.width, height: size.height))
    

    with:

    img.draw(in: getAspectFitFrame(sizeImgView: size, sizeImage: img.size))
    
  2. When calculating aspect you center image horizontally/vertically if its width/height less then UIImageView width/height. But instead of comparing newWidth and newHeight you should compare factors:

    if hfactor > vfactor {
        y = (sizeImgView.height - newHeight) / 2
    } else {
        x = (sizeImgView.width - newWidth) / 2
    }
    

嗨,Michael,感谢你的回答。这里有一个小问题。由于两个图像的大小不同,在合并后,UIImage B 的原点变化明显。我该怎么做才能获得相对于原始图像大小(即 UIImage A)的确切原点? - Hemang
@Hemang 我在不同的模拟器上进行了测试,使用你提供的源代码合并后,我没有看到任何起源变化。你可以另外提一个问题吗? - mixel
谢谢,Michael,这是新的问题 - Hemang

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接