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

时间:2014-01-26 17:05:11

标签: ios iphone objective-c uiimage

我目前的组合UIImages的方法来自于answer上的SO,以及this关于使用宽高比调整UIImage大小的流行问题。我目前的问题如下:

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

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

结果如下 -

在结合UIImages之前

enter image description here

合并图像后

enter image description here

请注意,底层图片未拉伸。但是,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();

4 个答案:

答案 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;