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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9208951/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 16:43:34  来源:igfitidea点击:

iOS - Merging two images of different size

objective-cioscocoa-touchmergeuiimage

提问by elio.d

I'm facing the following problem : I have to merge two images A and B to create a new image C as a result of the merging.
I already know how to merge two images but in this case my goal is a little bit different.
I would like that image A will be the background for Image B.
For instance if image A size is 500x500 and image B size is 460x460 I would like that image C (the image result of the merging) will be 500x500, with image B (460x460) centered in it.

我面临以下问题:由于合并,我必须合并两个图像 A 和 B 以创建新图像 C。
我已经知道如何合并两个图像,但在这种情况下,我的目标有点不同。
我希望图像 A 将成为图像 B 的背景。
例如,如果图像 A 大小为 500x500,图像 B 大小为 460x460,我希望图像 C(合并的图像结果)为 500x500,图像 B( 460x460) 居中。

Thanks in advance for any help or suggestion

在此先感谢您的任何帮助或建议

回答by Srikar Appalaraju

This is what I've done in my app, but without using UIImageView:

这是我在我的应用程序中所做的,但没有使用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();

If the image already has opacity, you do not need to set it (as in bottomImage) otherwise you can set it (as with image).

如果图像已经具有不透明度,则不需要设置它(如底部图像),否则您可以设置它(如图像)。

After this UIImageis created then you can embed it in your UIImageView

在这之后UIImage创建,那么你可以将它嵌入到你的UIImageView

UPDATE: Thanks to Ahmet AkkoK - for Swift (2.2) users blend mode macro has changed. CGBlendMode .kCGBlendModeNormalis replaced with CGBlendMode.Normal

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

回答by USK

Hey i got multiple images add same background with different foreground This is my code

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

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];

回答by Maxim Shoustin

Swift version

迅捷版

Copy/Paste to Playground

复制/粘贴到 Playground

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

在此处输入图片说明



To load images from playground:

从 Playground 加载图像:

  • Open playgroundfile and create there folder Resources
  • copy images to this folder
  • 打开playground文件并在那里创建文件夹Resources
  • 将图像复制到此文件夹

enter image description here

在此处输入图片说明

回答by Thiru

Just made quick paste function for those of you who wanted to use Srikar Appalanswer. (if in case background & foreground images are of different sizes)

刚刚为那些想要使用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;
}

回答by Dara Tith

in 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()

回答by Dara Tith

You can go with another trickas described below:

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

  1. Add first image to a imageView.
  2. Add second image to another imageView.
  3. Add both the above imageViews in a single main imageView and access the combined image by property of imageView : mainImageView.image
  1. 将第一张图像添加到 imageView。
  2. 将第二张图片添加到另一个 imageView。
  3. 在单个主imageView 中添加上述两个imageViews并通过imageView 的属性访问组合图像:mainImageView.image

Have a look at the code below :

看看下面的代码:

    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();

回答by bikram990

Thanks @Srikar Appal for iOS soultion.

感谢 @Srikar Appal 为 iOS 解决方案。

For anyone who is looking for merge in OS X:

对于在 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;
}