如何合并两个UIImages,同时保持长宽比和大小?

代码被添加到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大小查找子视图的来源

以下是了解问题的截图:

在这里输入图像说明

我应该怎么做才能得到合并函数的正确输出?

你的代码中有两个错误:

  1. 您还应该计算文档图像的宽高比以适合UIImageView 。 在mergeImages()replace:

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

    有:

     img.draw(in: getAspectFitFrame(sizeImgView: size, sizeImage: img.size)) 
  2. 在计算纵横比时,如果图像的宽度/高度小于UIImageView宽度/高度,则将图像水平/垂直居中。 但不是比较newWidthnewHeight你应该比较一下因素:

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

试试波纹pipe代码对我有用,希望它也适用于你,

 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 }