Skip to content

Instantly share code, notes, and snippets.

@mingsai
Created February 12, 2016 17:59
Show Gist options
  • Select an option

  • Save mingsai/43a2a17c52682d3ddf47 to your computer and use it in GitHub Desktop.

Select an option

Save mingsai/43a2a17c52682d3ddf47 to your computer and use it in GitHub Desktop.
A Swift core image extension for producing a collage image when given an array of images.
//
// MNGCoreImageExtensions.swift
//
//
// Created by Tommie N. Carter, Jr., MBA on 7/28/15.
// Copyright © 2015 MING Technology. All rights reserved.
//
import CoreImage
import UIKit
//class MNGCoreImageExtensions: NSObject {
//
//}
extension CIImage {
//CGContextDrawImage
class func collageImage (rect: CGRect, images: [UIImage]) -> UIImage {
let maxImagesPerRow = 9
var maxSide : CGFloat = 0.0
if images.count >= maxImagesPerRow {
maxSide = max(rect.width / CGFloat(maxImagesPerRow), rect.height / CGFloat(maxImagesPerRow))
} else {
maxSide = max(rect.width / CGFloat(images.count), rect.height / CGFloat(images.count))
}
var index = 0
var currentRow = 1
var xtransform:CGFloat = 0.0
var ytransform:CGFloat = 0.0
var smallRect:CGRect = CGRectZero
var composite: CIImage? // used to hold the composite of the images
for img in images {
let x = ++index % maxImagesPerRow //row should change when modulus is 0
//row changes when modulus of counter returns zero @ maxImagesPerRow
if x == 0 {
//last column of current row
smallRect = CGRectMake(xtransform, ytransform, maxSide, maxSide)
//reset for new row
++currentRow
xtransform = 0.0
ytransform = (maxSide * CGFloat(currentRow - 1))
} else {
//not a new row
smallRect = CGRectMake(xtransform, ytransform, maxSide, maxSide)
xtransform += CGFloat(maxSide)
}
// Note, this section could be done with a single transform and perhaps increase the
// efficiency a bit, but I wanted it to be explicit.
//
// It will also use the CI coordinate system which is bottom up, so you can translate
// if the order of your collage matters.
//
// Also, note that this happens on the GPU, and these translation steps don't happen
// as they are called... they happen at once when the image is rendered. CIImage can
// be thought of as a recipe for the final image.
//
// Finally, you an use core image filters for this and perhaps make it more efficient.
// This version relies on the convenience methods for applying transforms, etc, but
// under the hood they use CIFilters
var ci = CIImage(image: img)!
ci = ci.imageByApplyingTransform(CGAffineTransformMakeScale(maxSide / img.size.width, maxSide / img.size.height))
ci = ci.imageByApplyingTransform(CGAffineTransformMakeTranslation(-smallRect.origin.x, -smallRect.origin.y))
if composite == nil {
composite = ci
} else {
composite = ci.imageByCompositingOverImage(composite!)
}
}
let cgIntermediate = CIContext(options: nil).createCGImage(composite!, fromRect: composite!.extent)
let finalRenderedComposite = UIImage(CGImage: cgIntermediate)
return finalRenderedComposite
}
}
@socheat-leang
Copy link

may you demo your result ?./

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment