ios 如何将 2 张图像合并/合并为 1 张

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9257992/
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:49:26  来源:igfitidea点击:

How to combine/ merge 2 images into 1

iphoneiosxcodeuiimageviewuiimage

提问by Desmond

I would like to know what to do to save 2 images into 1 image.

我想知道如何将 2 张图像保存为 1 张图像。

One of the photos can be moved, rotated and zoomed in/out...

其中一张照片可以移动、旋转和放大/缩小...

I'm doing this, but it basically captures all the stuff on the screen including my buttons...

我正在这样做,但它基本上捕获了屏幕上的所有内容,包括我的按钮......

UIGraphicsBeginImageContext(self.view.bounds.size);
[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *savedImg = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

采纳答案by Swapnil Luktuke

  1. Create a subview for adding images.
  2. Add all your images in that view instead of the main view.
  3. Let the buttons and other stuff stay on the main view.
  4. Render only the view with images in the bitmap context instead of the main view like you are doing right now.
  1. 创建用于添加图像的子视图。
  2. 在该视图而不是主视图中添加所有图像。
  3. 让按钮和其他东西留在主视图上。
  4. 在位图上下文中仅渲染带有图像的视图,而不是像您现在所做的那样主视图。

回答by Vlad

You can create graphics context and draw both images in it. You'll get an image result from both your source images combined.

您可以创建图形上下文并在其中绘制两个图像。您将从合并的两个源图像中获得图像结果。

- (UIImage*)imageByCombiningImage:(UIImage*)firstImage withImage:(UIImage*)secondImage {
    UIImage *image = nil;

    CGSize newImageSize = CGSizeMake(MAX(firstImage.size.width, secondImage.size.width), MAX(firstImage.size.height, secondImage.size.height));
    if (UIGraphicsBeginImageContextWithOptions != NULL) {
        UIGraphicsBeginImageContextWithOptions(newImageSize, NO, [[UIScreen mainScreen] scale]);
    } else {
        UIGraphicsBeginImageContext(newImageSize); 
    }
    [firstImage drawAtPoint:CGPointMake(roundf((newImageSize.width-firstImage.size.width)/2), 
                                        roundf((newImageSize.height-firstImage.size.height)/2))]; 
    [secondImage drawAtPoint:CGPointMake(roundf((newImageSize.width-secondImage.size.width)/2), 
                                         roundf((newImageSize.height-secondImage.size.height)/2))]; 
    image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return image;
}

回答by Himanshu padia

Swift 4.2

斯威夫特 4.2

let topImage = UIImage(named: "image1.png")
let bottomImage = UIImage(named: "image2.png")

let size = CGSize(width: topImage!.size.width, height: topImage!.size.height + bottomImage!.size.height)
UIGraphicsBeginImageContextWithOptions(size, false, 0.0)

topImage!.draw(in: CGRect(x: 0, y: 0, width: size.width, height: topImage!.size.height))
bottomImage!.draw(in: CGRect(x: 0, y: topImage!.size.height, width: size.width, height: bottomImage!.size.height))

let newImage:UIImage = UIGraphicsGetImageFromCurrentImageContext()!
UIGraphicsEndImageContext()

//set finalImage to IBOulet UIImageView
mergeImage.image = newImage

Objective-C

目标-C

UIImage *image1 = [UIImage imageNamed:@"image1.png"];
UIImage *image2 = [UIImage imageNamed:@"image2.png"];

CGSize size = CGSizeMake(image1.size.width, image1.size.height + image2.size.height);

UIGraphicsBeginImageContext(size);

[image1 drawInRect:CGRectMake(0,0,size.width, image1.size.height)];
[image2 drawInRect:CGRectMake(0,image1.size.height,size.width, image2.size.height)];

UIImage *finalImage = UIGraphicsGetImageFromCurrentImageContext();

UIGraphicsEndImageContext();

//set finalImage to IBOulet UIImageView
imageView.image = finalImage;

回答by mourodrigo

Swift 3

斯威夫特 3

In this example the frontImage is being drawn inside the other image using a insetBy of 20% margin.

在这个例子中,frontImage 使用 20% 边距的 insetBy 被绘制在另一个图像内。

The background image must be drawn before and then the front image in sequence.

必须先绘制背景图,然后按顺序绘制正面图。

I used this to place a "Play" icon image in front a video frame image inside a UIImageView like below:

我用它在 UIImageView 内的视频帧图像前面放置了一个“播放”图标图像,如下所示:

enter image description here

在此处输入图片说明

Usage:

用法:

self.image = self.mergedImageWith(frontImage: UIImage.init(named: "play.png"), backgroundImage: UIImage.init(named: "backgroundImage.png")))

Method:

方法:

func mergedImageWith(frontImage:UIImage?, backgroundImage: UIImage?) -> UIImage{

    if (backgroundImage == nil) {
        return frontImage!
    }

    let size = self.frame.size
    UIGraphicsBeginImageContextWithOptions(size, false, 0.0)

    backgroundImage?.draw(in: CGRect.init(x: 0, y: 0, width: size.width, height: size.height))
    frontImage?.draw(in: CGRect.init(x: 0, y: 0, width: size.width, height: size.height).insetBy(dx: size.width * 0.2, dy: size.height * 0.2))

    let newImage:UIImage = UIGraphicsGetImageFromCurrentImageContext()!
    UIGraphicsEndImageContext()

    return newImage
}

回答by Parvez Belim

You can use this method, which is very dynamic and you can specify the starting position of the second image and total size of the image.

你可以使用这个方法,它非常动态,你可以指定第二张图像的起始位置和图像的总大小。

-(UIImage *) addImageToImage:(UIImage *)img withImage2:(UIImage *)img2 andRect:(CGRect)cropRect withImageWidth:(int) width     
{

    CGSize size = CGSizeMake(width,40);
    UIGraphicsBeginImageContext(size);

    CGPoint pointImg1 = CGPointMake(0,0);
    [img drawAtPoint:pointImg1];

     CGPoint pointImg2 = cropRect.origin;
     [img2 drawAtPoint: pointImg2];

     UIImage* result = UIGraphicsGetImageFromCurrentImageContext();
     UIGraphicsEndImageContext();
     return result;
}

回答by Alexander Borisenko

Here's a method for UIImage extension to combine multiple images:

这是 UIImage 扩展组合多个图像的方法:

class func combine(images: UIImage...) -> UIImage {
    var contextSize = CGSizeZero

    for image in images {
        contextSize.width = max(contextSize.width, image.size.width)
        contextSize.height = max(contextSize.height, image.size.height)
    }

    UIGraphicsBeginImageContextWithOptions(contextSize, false, UIScreen.mainScreen().scale)

    for image in images {
        let originX = (contextSize.width - image.size.width) / 2
        let originY = (contextSize.height - image.size.height) / 2

        image.drawInRect(CGRectMake(originX, originY, image.size.width, image.size.height))
    }

    let combinedImage = UIGraphicsGetImageFromCurrentImageContext()

    UIGraphicsEndImageContext()

    return combinedImage
}

Example:

例子:

UIImage.combine(image1, image2)

回答by ramchandra n

Swift-3 (IOS10.3)

Swift-3 ( IOS10.3)

extension UIImage {
    func combineWith(image: UIImage) -> UIImage {
        let size = CGSize(width: self.size.width, height: self.size.height + image.size.height)
        UIGraphicsBeginImageContextWithOptions(size, false, 0.0)

        self.draw(in: CGRect(x:0 , y: 0, width: size.width, height: self.size.height))
        image.draw(in: CGRect(x: 0, y: self.size.height, width: size.width,  height: image.size.height))

        let newImage: UIImage = UIGraphicsGetImageFromCurrentImageContext()!
        UIGraphicsEndImageContext()

        return newImage
    }
}

Usage

用法

let image1 = UIImage(named: "image1.jpg")
let image2 = UIImage(named: "image2.jpg")

yourImageView.image = image1?.combineWith(image: image2)

回答by Gabi Dj

Based on Himanshu padia's response

基于Himanshu padia的回应

If you want to "dynamically" combine more images (with the same aspect ratio) into one grid in Objective-C

如果您想“动态”将更多图像(具有相同纵横比)组合到一个网格中 Objective-C

I have used only two for this example on even/odd slots.

在偶数/奇数插槽上,我仅在此示例中使用了两个。

Formulas for equal inline and outline border:

相等的内联和轮廓边框的公式:

// psx = (x - (n+1)*bs / n)
// psy = (y - (m+1)*bs / m)

Formulas for different inline and outline border

不同内联和大纲边框的公式

// psx = (x - (n-1)*bs + obs / n)
// psy = (y - (m-1)*bs + obs / m)

Explanation:

解释:

  • psx, psy - piece size X and y
  • x, y - original (piece) image size
  • n, m - pieces slots in grid
  • bs - border size
  • obs - outline border size

  • Why n+1 ? Because for three pieces, you need 4 borders |*|*|*|

  • Why n-1 ? Because same as above, but excluding the first and last border !*|*|*!

  • psx, psy - 件尺寸 X 和 y
  • x, y - 原始(片)图像大小
  • n, m - 网格中的插槽
  • bs - 边框大小
  • obs - 轮廓边框大小

  • 为什么是 n+1 ?因为对于三块,你需要 4 个边框 |*|*|*|

  • 为什么是 n-1 ?因为同上,但不包括第一个和最后一个边框 !*|*|*!

Code:

代码:

UIImage *image1 = [UIImage imageNamed:@"14x9blue"];
UIImage *image2 = [UIImage imageNamed:@"14x9red"];

// grid parameters
int k =0;
int m=3,n = 3;
int i=0, j=0;

CGFloat borderSize = 20.0f;
//  equal border inline and outline
// the 1 is a multiplier for easier and more dynamic sizes
// 0*borderSize is inline border only, 1 is equal, 2 is double, etc.
CGFloat outlineBorder = 1*borderSize;

CGSize size = CGSizeMake(self.gridImageView.image.size.width, self.gridImageView.image.size.height);
CGRect gridImage = CGRectMake(0,0, size.width, size.height);


// piece size
// border inline and outline    
// psx = (x - (n-1)*bs + obs / n)
// psy = (y - (m-1)*bs + obs / m)
CGFloat pieceSizeX = (size.width - (n-1)*borderSize - 2*outlineBorder) / n;
CGFloat pieceSizeY = (size.height - (m-1)*borderSize - 2*outlineBorder) / m;




UIGraphicsBeginImageContext(size);
// semi transparent fill
[[UIColor colorWithDisplayP3Red:240 green:250 blue:0 alpha:0.5] setFill];
UIRectFill(CGRectMake(0,0, size.width, size.height));

UIImage *currentImage;
for(i=0; i<m; i++) {
    for (j=0; j<n; j++) {
        if (k++%2) {
            currentImage = image1;
        } else {
            currentImage = image2;
        }
        // 10-60 , 70-120, 130-180
        [currentImage drawInRect:CGRectMake(
                outlineBorder + (i)*borderSize + i*pieceSizeX,
                outlineBorder + (j)*borderSize + j*pieceSizeY,
                pieceSizeX,
                pieceSizeY
        )
        ];
    }
}

UIImage *finalImage = UIGraphicsGetImageFromCurrentImageContext();

UIGraphicsEndImageContext();

//set finalImage to IBOulet UIImageView
self.gridImageView.image = finalImage;

Grid with equal borders

具有相等边框的网格