iOS - 合并两个不同大小的图像

时间:2012-02-09 10:16:12

标签: objective-c ios cocoa-touch merge uiimage

我遇到以下问题:由于合并,我必须合并两个图像A和B以创建新图像C. 我已经知道如何合并两个图像但在这种情况下我的目标有点不同 我想图像A将是图像B的背景。
例如,如果图像A尺寸为500x500且图像B尺寸为460x460,我希望图像C(合并的图像结果)为500x500,图像B(460x460)位于其中心。

提前感谢您的任何帮助或建议

7 个答案:

答案 0 :(得分:85)

这是我在我的应用中所做的,但没有使用UIImageView

UIImage *bottomImage = [UIImage imageNamed:@"bottom.png"]; //background image
UIImage *image       = [UIImage imageNamed:@"top.png"]; //foreground image

CGSize newSize = CGSizeMake(width, height);
UIGraphicsBeginImageContext( newSize );

// Use existing opacity as is
[bottomImage drawInRect:CGRectMake(0,0,newSize.width,newSize.height)];

// Apply supplied opacity if applicable
[image drawInRect:CGRectMake(0,0,newSize.width,newSize.height) blendMode:kCGBlendModeNormal alpha:0.8];

UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();

UIGraphicsEndImageContext();

如果图像已经具有不透明度,则无需设置它(如在bottomImage中),否则可以设置它(与图像一样)。

创建此UIImage后,您可以将其嵌入UIImageView

更新:感谢Ahmet AkkoK - 对于Swift(2.2)用户,混合模式宏已经改变。 CGBlendMode .kCGBlendModeNormal替换为CGBlendMode.Normal

答案 1 :(得分:11)

嘿,我有多个图像添加相同的背景与不同的前景 这是我的代码

UIImage *bottomImage = [UIImage imageNamed:@"photo 2.JPG"]; //background image
UIImage *image       = [UIImage imageNamed:@"photo 3.JPG"]; //foreground image
UIImage *image1      = [UIImage imageNamed:@"photo 4.JPG"]; //foreground image
UIImage *image2      = [UIImage imageNamed:@"photo 5.JPG"]; //foreground image

CGSize newSize = CGSizeMake(320, 480);
UIGraphicsBeginImageContext( newSize );

// Use existing opacity as is
[bottomImage drawInRect:CGRectMake(0,0,newSize.width,newSize.height)];

// Apply supplied opacity if applicable
[image drawInRect:CGRectMake(0,0,newSize.width,newSize.height) blendMode:kCGBlendModeNormal alpha:0.4];
[image1 drawInRect:CGRectMake(0,0,newSize.width,newSize.height) blendMode:kCGBlendModeNormal alpha:0.3];
[image2 drawInRect:CGRectMake(0,0,newSize.width,newSize.height) blendMode:kCGBlendModeNormal alpha:0.2];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();

UIGraphicsEndImageContext();

resultView = [[UIImageView alloc] initWithImage:newImage];
resultView.frame = CGRectMake(0, 0,320,460);
[self.view addSubview:resultView];

答案 2 :(得分:7)

Swift版本

复制/粘贴到游乐场

var bottomImage:UIImage = UIImage(named:"avatar_4.png") //background image

enter image description here

var imageTop:UIImage  = UIImage(named:"group_4.png")    //top image

enter image description here

var newSize = CGSizeMake(bottomImage.size.width, bottomImage.size.height)
UIGraphicsBeginImageContext( newSize )

bottomImage.drawInRect(CGRectMake(0,0,newSize.width,newSize.height))

// decrease top image to 36x36 
imageTop.drawInRect(CGRectMake(18,18,36,36), blendMode:kCGBlendModeNormal, alpha:1.0)

var newImage:UIImage = UIGraphicsGetImageFromCurrentImageContext()
var imageData = UIImagePNGRepresentation(newImage)

enter image description here


从操场上加载图片:

  • 打开playground文件并在其中创建文件夹Resources
  • 将图像复制到此文件夹

enter image description here

答案 3 :(得分:3)

为那些想要使用Srikar Appal答案的人做了快速粘贴功能。 (如果背景和前景图像的大小不同)

- (UIImage *) mergeImages:(NSString *)bgImageFileName foreGround:(NSString *)fgImageFileName  {
    UIImage *bottomImage = [UIImage imageNamed:bgImageFileName]; //background image
    UIImage *image       = [UIImage imageNamed:fgImageFileName]; //foreground image

    CGSize newSize = CGSizeMake(bottomImage.size.width, bottomImage.size.height);
    UIGraphicsBeginImageContext(newSize);

    // Use existing opacity as is
    [bottomImage drawInRect:CGRectMake(0,0,newSize.width,newSize.height)];

    // Apply supplied opacity if applicable
    // Change xPos, yPos if applicable
    [image drawInRect:CGRectMake(11,11,image.size.width,image.size.height) blendMode:kCGBlendModeNormal alpha:1.0];

    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();

    UIGraphicsEndImageContext();
    return newImage;
}

答案 4 :(得分:2)

在Swift中

let bottomImage = UIImage(named: "Bottom_Image.png")
    let frontImage = UIImage (named: "Front_Image.png")
    let size = CGSize(width: 67, height: 55)
    UIGraphicsBeginImageContext(size)
    let areaSize = CGRect(x: 0, y: 0, width: size.width, height: size.height)
    let frontImageSize = CGRect(x: 14, y: 3, width: 40, height: 40)
    bottomImage!.drawInRect(areaSize, blendMode: CGBlendMode.Normal, alpha:  1.0)
    frontImage!.drawInRect(frontImageSize, blendMode: CGBlendMode.Normal, alpha: 1.0)

    let newImage:UIImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()

答案 5 :(得分:0)

感谢@Srikar Appal for iOS soultion。

对于在OS X中寻找合并的任何人:

- (NSImage *) mergeImages:(NSString *)bgImageFileName foreGround:(NSString *)fgImageFileName {
    NSImage *bottomImage = [NSImage imageNamed:bgImageFileName];
    NSImage *overlayedImage = [NSImage imageNamed:fgImageFileName];

    NSSize newSize = NSMakeSize(bottomImage.size.width, bottomImage.size.height);
    NSSize overlaySize = NSMakeSize(newSize.width/2, newSize.height/2); //change the size according to your requirements

    NSImage *newImage = [[NSImage alloc] initWithSize:newSize];

    [newImage lockFocus];

    [bottomImage drawInRect:NSMakeRect(0, 0, newSize.width, newSize.height)];
    [overlayedImage drawInRect:NSMakeRect(newSize.width-overlaySize.width, 0, overlaySize.width, overlaySize.height)]; //set the position as required

    [newImage unlockFocus];

    return newImage;
}

答案 6 :(得分:0)

您可以使用另一个技巧,如下所述:

  1. 将第一张图片添加到imageView。
  2. 将第二张图片添加到另一张imageView。
  3. 在单个主imageView中添加上述imageViews并按imageView属性访问合并图像: mainImageView.image
  4. 看看下面的代码:

        CGRect rect= investmentDetailTblView.frame;
        int rows = investmentDetailArray.count;
    
        CGFloat heightFinal = 5;
        CGRect frame1;
    
        for (int i=0; i<rows; i++)
        {
             frame1 = [investmentDetailTblView rectForRowAtIndexPath:[NSIndexPath indexPathForRow:i inSection:0]];
            CGFloat height = frame1.size.height;
    
            heightFinal = heightFinal + height;
        }
        rect.size.height = heightFinal;
    
        investmentDetailTblView.frame=rect;
    
        UIImageView *imageViewTable = [[UIImageView alloc] init];
    
        [imageViewTable setFrame:CGRectMake(0, 0, frame1.size.width, heightFinal)];
    
    
        [investmentDetailTblView reloadData];
    
        if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)])
            UIGraphicsBeginImageContextWithOptions(investmentDetailTblView.bounds.size, NO, [UIScreen mainScreen].scale);
        else
            UIGraphicsBeginImageContext(investmentDetailTblView.bounds.size);
    
        [investmentDetailTblView.layer renderInContext:UIGraphicsGetCurrentContext()];
        UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
    
        imageViewTable.image = image; //Adding the table image to the image view.
    
    
        CGRect frame=CGRectMake(0, heightFinal+5, investmentDetailTblView.frame.size.width, 20) ;
        UIView *footerView=[DataStore kkrLogoView];
    
        footerView.frame=frame;
    
        if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)])
            UIGraphicsBeginImageContextWithOptions(footerView.frame.size, NO, [UIScreen mainScreen].scale);
        else
            UIGraphicsBeginImageContext(footerView.frame.size);
    
        [footerView.layer renderInContext:UIGraphicsGetCurrentContext()];
        UIImage *kkrLogoImage = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
    
        UIImageView *imageViewFooter = [[UIImageView alloc] init];
        [imageViewFooter setFrame:CGRectMake(0, heightFinal, footerView.frame.size.width, footerView.frame.size.height)];
        imageViewFooter.image = kkrLogoImage; //Adding the footer image to the image view.
    
    
        UIImageView *mainImageView = [[UIImageView alloc] init];
        [mainImageView setFrame:CGRectMake(0, 0, frame1.size.width, (heightFinal+footerView.frame.size.height))];
    
        [mainImageView addSubview:imageViewTable];
        [mainImageView addSubview:imageViewFooter];
    
        if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)])
            UIGraphicsBeginImageContextWithOptions(mainImageView.frame.size, NO, [UIScreen mainScreen].scale);
        else
            UIGraphicsBeginImageContext(mainImageView.frame.size);
    
        [mainImageView.layer renderInContext:UIGraphicsGetCurrentContext()];
        UIImage *finalImage = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();