How to merge two UIImages?

后端 未结 7 1587
野趣味
野趣味 2020-12-07 16:57

I am trying to merge two different images and create a new one. This is the way I would like to do: I have this image (A):

It\'s a PNG image and I would like to mer

相关标签:
7条回答
  • 2020-12-07 17:10

    Hope this may help you,

    var bottomImage = UIImage(named: "bottom.png")
    var topImage = UIImage(named: "top.png")
    
    var size = CGSize(width: 300, height: 300)
    UIGraphicsBeginImageContext(size)
    
    let areaSize = CGRect(x: 0, y: 0, width: size.width, height: size.height)
    bottomImage!.draw(in: areaSize)
    
    topImage!.draw(in: areaSize, blendMode: .normal, alpha: 0.8)
    
    var newImage:UIImage = UIGraphicsGetImageFromCurrentImageContext()!
    UIGraphicsEndImageContext()
    

    All the Best :)

    0 讨论(0)
  • 2020-12-07 17:11

    The upvoted answer stretches the background image changing its ratio. The solution below fixes that by rendering the image from a UIView that contains the two image views as subviews.

    ANSWER YOU ARE LOOKING FOR (Swift 4):

    func blendImages(_ img: UIImage,_ imgTwo: UIImage) -> Data? {
        let bottomImage = img
        let topImage = imgTwo
    
        let imgView = UIImageView(frame: CGRect(x: 0, y: 0, width: 306, height: 306))
        let imgView2 = UIImageView(frame: CGRect(x: 0, y: 0, width: 306, height: 306))
    
        // - Set Content mode to what you desire
        imgView.contentMode = .scaleAspectFill
        imgView2.contentMode = .scaleAspectFit
    
        // - Set Images
        imgView.image = bottomImage
        imgView2.image = topImage
    
        // - Create UIView
        let contentView = UIView(frame: CGRect(x: 0, y: 0, width: 306, height: 306))
        contentView.addSubview(imgView)
        contentView.addSubview(imgView2)
    
        // - Set Size
        let size = CGSize(width: 306, height: 306)
    
        // - Where the magic happens
        UIGraphicsBeginImageContextWithOptions(size, true, 0)
    
        contentView.drawHierarchy(in: contentView.bounds, afterScreenUpdates: true)
    
        guard let i = UIGraphicsGetImageFromCurrentImageContext(),
            let data = UIImageJPEGRepresentation(i, 1.0)
            else {return nil}
    
        UIGraphicsEndImageContext()
    
        return data
    }
    

    The returned image data doubles the size of the image, so set the size of the views at half the desired size.

    • EXAMPLE: I wanted the width and height of the image to be 612, so I set the view frames width and height to 306) // Enjoy :)
    0 讨论(0)
  • 2020-12-07 17:12

    Slightly modified version of answer by budidino. This implementation also handles negative posX and posY correctly.

    extension UIImage {
        func overlayWith(image: UIImage, posX: CGFloat, posY: CGFloat) -> UIImage {
            let newWidth = posX < 0 ? abs(posX) + max(self.size.width, image.size.width) :
                size.width < posX + image.size.width ? posX + image.size.width : size.width
            let newHeight = posY < 0 ? abs(posY) + max(size.height, image.size.height) :
                size.height < posY + image.size.height ? posY + image.size.height : size.height
            let newSize = CGSize(width: newWidth, height: newHeight)
    
            UIGraphicsBeginImageContextWithOptions(newSize, false, 0.0)
            let originalPoint = CGPoint(x: posX < 0 ? abs(posX) : 0, y: posY < 0 ? abs(posY) : 0)
            self.draw(in: CGRect(origin: originalPoint, size: self.size))
            let overLayPoint = CGPoint(x: posX < 0 ? 0 : posX, y: posY < 0 ? 0 : posY)
            image.draw(in: CGRect(origin: overLayPoint, size: image.size))
            let newImage = UIGraphicsGetImageFromCurrentImageContext()!
            UIGraphicsEndImageContext()
    
            return newImage
        }
    }
    
    0 讨论(0)
  • 2020-12-07 17:13

    This way the overlay picture will be much cleaner

    class func mergeImages(imageView: UIImageView) -> UIImage {
     UIGraphicsBeginImageContextWithOptions(imageView.frame.size, false, 0.0) 
     imageView.superview!.layer.renderInContext(UIGraphicsGetCurrentContext()!)
     let image = UIGraphicsGetImageFromCurrentImageContext()
     UIGraphicsEndImageContext()
    
     return image 
    }
    

    0 讨论(0)
  • 2020-12-07 17:17

    Swift 5: Extension for UIImage

    extension UIImage {
      func mergeWith(topImage: UIImage) -> UIImage {
        let bottomImage = self
    
        UIGraphicsBeginImageContext(size)
    
        let areaSize = CGRect(x: 0, y: 0, width: bottomImage.size.width, height: bottomImage.size.height)
        bottomImage.draw(in: areaSize)
    
        topImage.draw(in: areaSize, blendMode: .normal, alpha: 1.0)
    
        let mergedImage = UIGraphicsGetImageFromCurrentImageContext()!
        UIGraphicsEndImageContext()
        return mergedImage
      }
    }
    
    0 讨论(0)
  • 2020-12-07 17:23

    Objective C version of this solution with top image re-centered logic :

    -(UIImage *)getImageInclosedWithinAnotherImage
    {
        float innerImageSize = 20;
        UIImage *finalImage;
    
        UIImage *outerImage = [UIImage imageNamed:@"OuterImage.png"];
        UIImage *innerImage = [UIImage imageNamed:@"InnerImage.png"];
    
        CGSize outerImageSize = CGSizeMake(40, 40); // Provide custom size or size of your actual image
        UIGraphicsBeginImageContext(outerImageSize);
    
        //calculate areaSize for re-centered inner image
        CGRect areSize = CGRectMake(((outerImageSize.width/2) - (innerImageSize/2)), ((outerImageSize.width/2) - (innerImageSize/2)), innerImageSize, innerImageSize);
        [outerImage drawInRect:CGRectMake(0, 0, outerImageSize.width, outerImageSize.height)];
        [innerImage drawInRect:areSize blendMode:kCGBlendModeNormal alpha:1.0];
    
        finalImage = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
    
        return finalImage;
    }
    
    0 讨论(0)
提交回复
热议问题