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
How to combine/ merge 2 images into 1
提问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
- Create a subview for adding images.
- Add all your images in that view instead of the main view.
- Let the buttons and other stuff stay on the main view.
- Render only the view with images in the bitmap context instead of the main view like you are doing right now.
- 创建用于添加图像的子视图。
- 在该视图而不是主视图中添加所有图像。
- 让按钮和其他东西留在主视图上。
- 在位图上下文中仅渲染带有图像的视图,而不是像您现在所做的那样主视图。
回答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 内的视频帧图像前面放置了一个“播放”图标图像,如下所示:
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;