将2个UIImage视图与缩放和偏移相结合

时间:2014-06-10 04:21:37

标签: ios objective-c uiscrollview uiimage

感谢阅读。

我有一张背景图片和一张前景图片。前景图像位于UIScrollView中,因此可以调整大小并在背景图像上重新定位。背景图像设置为Aspect Fit。我有一个功能,将两个UIImages组合成一个新的UIImage。这样做很好,但我能做对的是一个视图与另一个视图的x,y坐标。

这里有一些代码:

CGFloat bgImageScale = self.backgroundImageView.bounds.size.height / self.bgImage.size.height; // Gives me the AspectFit scale.
CGFloat bgOffsetX = (self.backgroundImageView.bounds.size.width - self.bgImage.size.width * bgImageScale) / 2.0;
CGFloat bgOffsetY = 0.0;
CGFloat fgImageScale = self.fgImageScrollView.zoomScale;
CGFloat fgOffsetX = -self.fgImageScrollView.contentOffset.x;
CGFloat fgOffsetY = -self.fgImageScrollView.contentOffset.y;

CGPoint imageOffset = CGPointMake((fgOffsetX - bgOffsetX) * bgImageScale, (fgOffsetY - bgOffsetY) * bgImageScale);


[self.delegate completedOverlayImage:
  [self mergeImage:self.fgImage
         withImage:self.bgImage
        usingAlpha:0.5f
        withOffset:imageOffset
          andScale:fgImageScale / bgImageScale
]];

简而言之,compeletedOverlayImage代码执行以下相关位:

[bottomImage drawInRect:CGRectMake(0,0,newSize.width,newSize.height)];
[topImage drawInRect:CGRectMake(imageOffset.x, imageOffset.y, newSize.width*imageScale, newSize.height*imageScale) blendMode:kCGBlendModeNormal alpha:alpha];

所以我无法正确获取imageOffset,以使新图像与屏幕上显示的图像重叠。

顺便说一下,这款应用只适用于iOS 7及以上版本。

有人可以帮忙吗?感谢。

2 个答案:

答案 0 :(得分:0)

查看UIView convertRect:toView:方法。

假设您的视图层次结构如下所示

SomeViewController
   View               // the view controller's main view
      BgView          // the background view (UIImageView)
      ScrollView      
         FgView       // the foreground view (UIImageView)

如果前景图像是UIImageView,它是滚动视图的子项,那么您可以使用一行代码将FgView帧坐标转换为主视图坐标系

CGRect foregroundFrame = [self.foregroundImageView convertRect:self.foregroundImageView.bounds toView:self.view];

由于BgView的帧已经在mainView坐标中,因此这将为您提供相同坐标系中的两个帧。

答案 1 :(得分:0)

好的,我自己解决了。所以对于尝试同样事情的其他人来说,这里是代码:

CGFloat bgImageScale = self.backgroundImageView.bounds.size.height / self.bgImage.size.height;
CGFloat bgOffsetX = (self.backgroundImageView.bounds.size.width - self.bgImage.size.width * bgImageScale) / 2.0;
CGFloat bgOffsetY = 0.0;
CGFloat fgImageScale = self.fgImageScrollView.zoomScale;
CGFloat fgRelativeZoom = fgImageScale / bgImageScale; // How much is fg zoomed compared to bg?
CGFloat fgOffsetX = -self.fgImageScrollView.contentOffset.x; // We want the offset of the (0,0), not the offset of the viewport. Hence, negative.
CGFloat fgOffsetY = -self.fgImageScrollView.contentOffset.y;

CGPoint imageOffset = CGPointMake(fgOffsetX / bgImageScale - bgOffsetX, fgOffsetY / bgImageScale - bgOffsetY);

[self.delegate completedOverlayImage:
 [self mergeImage:self.fgImage
        withImage:self.bgImage
       usingAlpha:0.5f
       withOffset:imageOffset
         andScale:fgRelativeZoom
]];

和组合图像的功能(假设iOS 7允许你在UIGraphicsBeginContextWithOptions()调用中将比例设置为零):

- (UIImage*) mergeImage:(UIImage*)topImage withImage:(UIImage*)bottomImage usingAlpha:(CGFloat)alpha withOffset:(CGPoint)imageOffset andScale:(CGFloat)imageScale {

    int width = bottomImage.size.width;
    int height = bottomImage.size.height;

    CGSize newSize = CGSizeMake(width, height);

    UIGraphicsBeginImageContextWithOptions(newSize, NO, 0.0);
    [bottomImage drawInRect:CGRectMake(0,0,newSize.width,newSize.height)];
    [topImage drawInRect:CGRectMake(imageOffset.x, imageOffset.y, newSize.width*imageScale, newSize.height*imageScale) blendMode:kCGBlendModeNormal alpha:alpha];

    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return newImage;
}

希望能帮助其他人。