2

Trying to combine an array of images to a single image which looks like a long row of the images. (note: images may or may not be of similar sizes)

enter image description here

here is the code, which currently works for single size images only

func combine(images: NSMutableArray) -> UIImage {
    var contextSize = CGSizeZero
    var xMaxSize : CGFloat = 0
    for image in images {
       //

        xMaxSize = xMaxSize + image.size.width
        //contextSize.width = max(contextSize.width , image.size.width )
        contextSize.height = max(contextSize.height, image.size.height)
    }
    contextSize.width = xMaxSize

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


    var imageXPlace :CGFloat = 0

    for image in images {


        let originX = imageXPlace
        let originY = (contextSize.height - image.size.height) / 2


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

        imageXPlace = imageXPlace + image.size.width
    }

    let combinedImage = UIGraphicsGetImageFromCurrentImageContext()

    UIGraphicsEndImageContext()

    return combinedImage
}

This question is also related to this one

Community
  • 1
  • 1
chewy
  • 8,207
  • 6
  • 42
  • 70

1 Answers1

1
  • Images has different sizes
  • Height of the combined image - the smallest height in UIImage

ViewController.swift

import UIKit

struct ImageToCombine {
var image = UIImage()

var size: CGSize {
    get {
        return CGSize(width: image.size.width, height: image.size.height)
    }
}

var widthAndHeightRatio: CGFloat {
    get {
        return image.size.width/image.size.height
    }
}

init (image: UIImage) {
    self.image = image
}
}

class ViewController: UIViewController {

var imageView = UIImageView()
var images = [ImageToCombine]()

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.

    imageView = UIImageView(frame: UIScreen.mainScreen().bounds)
    imageView.contentMode = .ScaleAspectFit
    view.addSubview(imageView)

    images.append(ImageToCombine(image: UIImage(named: "image1")!))
    images.append(ImageToCombine(image: UIImage(named: "image2")!))
    images.append(ImageToCombine(image: UIImage(named: "image3")!))

    imageView.image = combine(images, spaceBetweenImages: 10)
}

func combine(images: [ImageToCombine], spaceBetweenImages:CGFloat) -> UIImage {

    var fullWidth:CGFloat = 0
    var minHeight:CGFloat = images[0].size.height

    for index in 0..<images.count {
        fullWidth += images[index].size.width
        if (index+1 < images.count) {
            fullWidth += spaceBetweenImages
        }
        if (minHeight > images[index].size.height) {
            minHeight = images[index].size.height
        }
    }

    let quality = CGFloat(4)
    let boundForBetter = CGRectMake(0, 0, fullWidth*quality, minHeight*quality)

    UIGraphicsBeginImageContext(boundForBetter.size)
    let context = UIGraphicsGetCurrentContext()

    for index in 0..<images.count {

        var imageX:CGFloat = 0
        for index2 in 0..<index {
            imageX += images[index2].size.width

            if (index2+1 < images.count) {
                imageX += spaceBetweenImages
            }
        }
        let imageY:CGFloat = (minHeight - images[index].size.height)*quality/2
        let rect = CGRect(x: imageX*quality, y: imageY, width: images[index].size.width*quality, height: images[index].size.height*quality)
        CGContextDrawImage(context, rect, images[index].image.CGImage)
    }

    let combinedImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()

    let resultImageimage = UIImage(CGImage: imageResize(combinedImage, sizeChange:CGSize(width: fullWidth/quality, height: minHeight/quality)).CGImage!, scale: 1.0, orientation: .DownMirrored)

    return resultImageimage
}

func imageResize(imageObj:UIImage, sizeChange:CGSize)-> UIImage {

    let hasAlpha = true
    let scale: CGFloat = 0.0 // Automatically use scale factor of main screen

    UIGraphicsBeginImageContextWithOptions(sizeChange, !hasAlpha, scale)
    imageObj.drawInRect(CGRect(origin: CGPointZero, size: sizeChange))

    let scaledImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext() // !!!
    return scaledImage
}
}

result:

enter image description here

Vasily Bodnarchuk
  • 24,482
  • 9
  • 132
  • 127
  • 1
    Thanks Vasily, when I tested your code with non equal sizes the result is a long image (as i should be) but the images are up-side-down. Any Idea? (your swift birds are also flying on the flip side of thing...) – chewy Aug 17 '16 at 13:39
  • Once more. Yo have different images as input array. Do you want to resize them? – Vasily Bodnarchuk Aug 17 '16 at 14:31
  • 1
    images should be the same size at the final single strip (.ScaleAspectFit is ok for different sizes) , but please look at the official swift logo opposing to the images you posted , they are flipped 180° standing on their heads... – chewy Aug 17 '16 at 14:53
  • You have a rather difficult task. I hope that helped. I have edited the answer – Vasily Bodnarchuk Aug 17 '16 at 16:59
  • Vasily , please clean up your answer, make the images smaller or remove them and I will be happy to accept your answer – chewy Aug 18 '16 at 06:37