如何在不改变原始高宽比的情况下合并两个不同大小的UIImage?

我目前的结合UIImage的方法来自于这个答案 ,以及这个普遍的问题调整UIImage纵横比。 我目前的问题如下:

我有一个叫做pictureImage的UIImage,用相机拍出来,标准尺寸是2448*3264 。 我也有一个叫做self.annotateView的UIImageView,它有一个320*568的框架,用户可以在这个框架上绘制和注释图片。 当我在UIImageView显示pictureImage时,我将图像显示设置为Aspect Fill,以便占用整个iPhone屏幕。 当然这意味着pictureImage部分在左右两边(实际上是两边的304像素)被截断,但是这是有意的。

我的问题是,当我将UIImage pictureImageannotateView.image结合到一个新的维度320*568 ,我的组合图像通过水平拉伸来改变annotateView.image的原始方面。 这很奇怪,因为新的尺寸正好是annotateView.image的原始尺寸。

这是结果的样子 –

在合并UIImages之前

在这里输入图像说明

合并后的图像

在这里输入图像说明

请注意,基础图片没有拉伸。 但是, annotateView.image只能水平拉伸,而不能垂直拉伸。

这是我合并UIImages的代码。

 //Note: self.firstTakenImage is set to 320*568 CGSize newSize = CGSizeMake(self.firstTakenImage.frame.size.width, self.firstTakenImage.frame.size.height); UIGraphicsBeginImageContext(newSize); [self.firstTakenImage.image drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)]; [self.drawView.image drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)]; UIImage *combinedImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); 

在执行drawInRect时,您必须重新使用AspectFill为系统做的缩放和居中,以使其与原始过程相匹配。 像这样的东西:

 CGSize fullSize = self.pictureView.image.size; CGSize newSize = self.outputView.frame.size; CGFloat scale = newSize.height/fullSize.height; CGFloat offset = (newSize.width - fullSize.width*scale)/2; CGRect offsetRect = CGRectMake(offset, 0, newSize.width-offset*2, newSize.height); NSLog(@"offset = %@",NSStringFromCGRect(offsetRect)); UIGraphicsBeginImageContext(newSize); [self.pictureView.image drawInRect:offsetRect]; [self.annotateView.image drawInRect:CGRectMake(0,0,newSize.width,newSize.height)]; UIImage *combImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); self.outputView.image = combImage; 
  • 支持纵向和横向两种types的图像
  • 绘图和其他子视图可以合并在我的情况下,我添加标签绘制
  { CGSize fullSize = getImageForEdit.size; CGSize sizeInView = AVMakeRectWithAspectRatioInsideRect(imgViewFake.image.size, imgViewFake.bounds).size; CGFloat orgScale = orgScale = fullSize.width/sizeInView.width; CGSize newSize = CGSizeMake(orgScale * img.image.size.width, orgScale * img.image.size.height); if(newSize.width <= fullSize.width && newSize.height <= fullSize.height){ newSize = fullSize; } CGRect offsetRect; if (getImageForEdit.size.height > getImageForEdit.size.width){ CGFloat scale = newSize.height/fullSize.height; CGFloat offset = (newSize.width - fullSize.width*scale)/2; offsetRect = CGRectMake(offset, 0, newSize.width-offset*2, newSize.height); } else{ CGFloat scale = newSize.width/fullSize.width; CGFloat offset = (newSize.height - fullSize.height*scale)/2; offsetRect = CGRectMake(0, offset, newSize.width, newSize.height-offset*2); } UIGraphicsBeginImageContextWithOptions(newSize, NO, getImageForEdit.scale); [getImageForEdit drawAtPoint:offsetRect.origin]; // [img.image drawInRect:CGRectMake(0,0,newSize.width,newSize.height)]; CGFloat oldScale = img.contentScaleFactor; img.contentScaleFactor = getImageForEdit.scale; [img drawViewHierarchyInRect:CGRectMake(0, 0, newSize.width, newSize.height) afterScreenUpdates:YES]; img.contentScaleFactor = oldScale; UIImage *combImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); imageData = UIImageJPEGRepresentation(combImage, 1); } 

当你调用[self.drawView.image drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)]; 您需要修改框架以说明您所描述的宽高比的差异(因为您正在两边切断一些图像)。

这意味着修改您正在绘制注释图像的x位置和width

修改是基于两个缩放之间的差异,当缩放到相同的高度。 你说这是304 ,所以你可以初始设置x为304, widthnewSize.width - 608来testing。 但真的差别应该计算…

Mackworth在Swift 3.x中的回答

  let fullSize:CGSize = img.size let newSize:CGSize = fullSize let scale:CGFloat = newSize.height/fullSize.height let offset:CGFloat = (newSize.width - fullSize.width*scale)/2 let offsetRect:CGRect = CGRect.init(x: offset, y: 0, width: newSize.width - offset*2, height: newSize.height) print(NSStringFromCGRect(offsetRect)) UIGraphicsBeginImageContext(newSize); self.pictureView.image.draw(in: offsetRect) self.annotateView.image.draw(in: CGRect.init(x: 0, y: 0, width: waterMarkImage.size.width, height: waterMarkImage.size.height)) let combImage:UIImage = UIGraphicsGetImageFromCurrentImageContext()! UIGraphicsEndImageContext(); return combImage;