我目前的组合UIImages的方法来自于answer上的SO,以及this关于使用宽高比调整UIImage大小的流行问题。我目前的问题如下:
我有一个名为pictureImage
的UIImage,它带有标准尺寸2448*3264
的相机。我还有一个名为self.annotateView
的UIImageView,其框架为320*568
,用户可以在其中绘制和注释图片。当我在pictureImage
中展示UIImageView
时,我将图片展示设置为 Aspect Fill ,以便它占据整个iPhone屏幕。当然这意味着pictureImage
的部分左右都被截断(实际上两边都是304像素),但这是有目的的。
我的问题是,当我将UIImages pictureImage
和annotateView.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();
答案 0 :(得分:3)
在执行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;
答案 1 :(得分:2)
{
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);
}
答案 2 :(得分:1)
当您致电[self.drawView.image drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)];
时,您需要修改相框以说明您描述的宽高比差异(因为您正在切断两侧的部分图像)。
这意味着修改您正在绘制注释图像的x
位置和width
。
修改基于缩放到相同高度时2个rects之间的差异。您说这是304
,因此您最初可以将x
设置为304,将width
设置为newSize.width - 608
进行测试。但真的应该计算差异......
答案 3 :(得分:0)
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;