【问题标题】:How to combine/ merge 2 images into 1如何将 2 张图像合并/合并为 1 张图像
【发布时间】:2012-03-04 16:56:07
【问题描述】:

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

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

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

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

【问题讨论】:

标签: iphone ios xcode uiimageview uiimage


【解决方案1】:
  1. 创建用于添加图像的子视图。
  2. 将所有图像添加到该视图而不是主视图中。
  3. 让按钮和其他内容留在主视图中。
  4. 仅在位图上下文中渲染带有图像的视图,而不是像您现在所做的那样渲染主视图。

【讨论】:

  • 谢谢,我想这是最好的方法 :)
【解决方案2】:

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

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

【讨论】:

  • 嗨弗拉德,感谢您的代码。它可以工作,但不会保存我编辑的任何移动或旋转。它还保存在图片的纵横比中。有什么建议吗?
  • 很高兴它有效。不知道你在追求什么?在您在运行时编辑图像时?还是只是缩放、移动和旋转?
  • 只是缩放、移动和旋转。然后保存以备不时之需
  • 当两个图像具有相同的大小时,此函数会失败(然后 MAX(first-width, second-width) 结果为 0;另外,drawAtPoint 函数似乎很无聊。我不得不交换它们与此: [firstImage drawAtPoint:CGPointMake(0,0)]; [secondImage drawAtPoint:CGPointMake(0, firstImage.size.height)]; 这仅适用于两个图像具有相同的宽度!
  • 对我来说,图像大小增加了 6 到 7 倍。有什么办法可以在相同质量的情况下保持较小的尺寸?
【解决方案3】:

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

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

【讨论】:

    【解决方案4】:

    斯威夫特 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

    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;
    

    【讨论】:

      【解决方案5】:

      这是一个 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
      }
      

      例子:

      UIImage.combine(image1, image2)
      

      【讨论】:

        【解决方案6】:

        斯威夫特 3

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

        必须先画背景图,再画前图。

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

        用法:

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

        方法:

        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
        }
        

        【讨论】:

          【解决方案7】:

          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
              }
          }
          

          用法

          let image1 = UIImage(named: "image1.jpg")
          let image2 = UIImage(named: "image2.jpg")
          
          yourImageView.image = image1?.combineWith(image: image2)
          

          【讨论】:

            【解决方案8】:

            基于Himanshu padia的回应

            如果你想在Objective-CObjective-C中“动态地”将更多图像(具有相同的宽高比)合并到一个网格中

            我在这个例子中只使用了两个偶数/奇数槽。

            内联和外边框相等的公式:

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

            不同内嵌和外框边框的公式

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

            解释:

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

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

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

            代码:

            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;
            

            【讨论】:

              猜你喜欢
              • 2011-05-24
              • 2013-07-18
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2022-07-01
              • 2017-09-18
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多