Last active
February 12, 2016 18:06
-
-
Save mingsai/84a26e0e0574f02a6a4d to your computer and use it in GitHub Desktop.
A swift extension to create an image from a font with a particular size, and many other image functions.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// MNGImageExtensions-2.swift | |
// | |
// | |
// Created by Tommie Carter on 7/2/15. | |
// Copyright © 2015 MING Technology. All rights reserved. | |
// | |
import UIKit | |
import AVFoundation | |
import AssetsLibrary | |
import Photos | |
struct MNGImageEvents { | |
static let ImageErrorSavingToPhotosLibrary = "ImageErrorSavingToPhotosLibrary" | |
static let ImageSavedToPhotosLibrary = "ImageSavedToPhotosLibrary" | |
static let ImageRemovedFromPhotosLibrary = "ImageRemovedFromPhotosLibrary" | |
static let ImageErrorSavingToAssetsLibrary = "ImageErrorSavingToAssetsLibrary" | |
static let ImageSavedToAssetsLibrary = "ImageSavedToAssetsLibrary" | |
static let ImageRemovedFromAssetsLibrary = "ImageRemovedFromAssetsLibrary" | |
} | |
extension UIImage { | |
func fixOrientation () -> UIImage { | |
// No-op if the orientation is already correct | |
guard (self.imageOrientation == UIImageOrientation.Up) else { return self } | |
// We need to calculate the proper transformation to make the image upright. | |
// We do it in 2 steps: Rotate if Left/Right/Down, and then flip if Mirrored. | |
var transform = CGAffineTransformIdentity; | |
switch (self.imageOrientation) { | |
//case : | |
case UIImageOrientation.Down, UIImageOrientation.DownMirrored: | |
transform = CGAffineTransformTranslate(transform, self.size.width, self.size.height); | |
transform = CGAffineTransformRotate(transform, CGFloat(M_PI)); | |
break; | |
//case : | |
case UIImageOrientation.Left, UIImageOrientation.LeftMirrored: | |
transform = CGAffineTransformTranslate(transform, self.size.width, 0); | |
transform = CGAffineTransformRotate(transform, CGFloat(M_PI_2)); | |
break; | |
//case : | |
case UIImageOrientation.Right, UIImageOrientation.RightMirrored: | |
transform = CGAffineTransformTranslate(transform, 0, self.size.height); | |
transform = CGAffineTransformRotate(transform, -CGFloat(M_PI_2)); | |
break; | |
//case : | |
case UIImageOrientation.Up, UIImageOrientation.UpMirrored: | |
break; | |
} | |
switch (self.imageOrientation) { | |
//case : | |
case UIImageOrientation.UpMirrored, UIImageOrientation.DownMirrored: | |
transform = CGAffineTransformTranslate(transform, self.size.width, 0); | |
transform = CGAffineTransformScale(transform, -1, 1); | |
break; | |
//case : | |
case UIImageOrientation.LeftMirrored, UIImageOrientation.RightMirrored: | |
transform = CGAffineTransformTranslate(transform, self.size.height, 0); | |
transform = CGAffineTransformScale(transform, -1, 1); | |
break; | |
//case : | |
case UIImageOrientation.Up, UIImageOrientation.Down, UIImageOrientation.Left,UIImageOrientation.Right: | |
break; | |
} | |
// Now we draw the underlying CGImage into a new context, applying the transform | |
// calculated above. | |
// let colorSpace:CGColorSpace = CGColorSpaceCreateDeviceRGB()! | |
// let bitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.PremultipliedLast.rawValue) | |
// let context = CGBitmapContextCreate(nil, Int(self.size.width), Int(self.size.height), 8, 0, colorSpace, bitmapInfo.rawValue) | |
let ctx = CGBitmapContextCreate(nil, Int(self.size.width), Int(self.size.height), | |
CGImageGetBitsPerComponent(self.CGImage), 0, | |
CGImageGetColorSpace(self.CGImage), | |
CGImageGetBitmapInfo(self.CGImage).rawValue); | |
CGContextConcatCTM(ctx, transform); | |
switch (self.imageOrientation) { | |
case UIImageOrientation.Left, UIImageOrientation.LeftMirrored, UIImageOrientation.Right, UIImageOrientation.RightMirrored: | |
// Grr... | |
CGContextDrawImage(ctx, CGRectMake(0,0,self.size.height,self.size.width), self.CGImage); | |
break; | |
default: | |
CGContextDrawImage(ctx, CGRectMake(0,0,self.size.width,self.size.height), self.CGImage); | |
break; | |
} | |
// And now we just create a new UIImage from the drawing context | |
let cgimg = CGBitmapContextCreateImage(ctx) | |
let img = UIImage(CGImage: cgimg!) | |
return img | |
} | |
func tintImageWithColor (color:UIColor, completionHandler:(image:UIImage)->()) { | |
dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0), { () -> Void in | |
UIGraphicsBeginImageContextWithOptions(self.size, false, self.scale) | |
let context = UIGraphicsGetCurrentContext() | |
CGContextTranslateCTM(context, 0, self.size.height) | |
CGContextScaleCTM(context, 1.0, -1.0) | |
CGContextSetBlendMode(context, CGBlendMode.Normal) | |
let rect = CGRectMake(0, 0, self.size.width, self.size.height) | |
CGContextClipToMask(context, rect, self.CGImage) | |
color.setFill() | |
CGContextFillRect(context, rect) | |
let newImage = UIGraphicsGetImageFromCurrentImageContext() | |
UIGraphicsEndImageContext() | |
//return newImage | |
dispatch_async(dispatch_get_main_queue(), { () -> Void in | |
completionHandler(image: newImage) | |
}) | |
}) | |
} | |
class func imageWithColor (color:UIColor, completionHandler:(image:UIImage)->()) { | |
dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0), { () -> Void in | |
let rect = CGRectInset(CGRectZero, -1.0, -1.0) | |
UIGraphicsBeginImageContext(rect.size) | |
let context = UIGraphicsGetCurrentContext() | |
CGContextSetFillColorWithColor(context, color.CGColor) | |
CGContextFillRect(context, rect) | |
let image = UIGraphicsGetImageFromCurrentImageContext() | |
UIGraphicsEndImageContext() | |
//return image | |
dispatch_async(dispatch_get_main_queue(), { () -> Void in | |
completionHandler(image: image) | |
}) | |
}) | |
} | |
class func imageWithColor (color:UIColor,forRect rect:CGRect, completionHandler:(image:UIImage)->()) { | |
dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0), { () -> Void in | |
//let rect = CGRectInset(CGRectZero, -1.0, -1.0) | |
UIGraphicsBeginImageContext(rect.size) | |
let context = UIGraphicsGetCurrentContext() | |
CGContextSetFillColorWithColor(context, color.CGColor) | |
CGContextFillRect(context, rect) | |
let image = UIGraphicsGetImageFromCurrentImageContext() | |
UIGraphicsEndImageContext() | |
//return image | |
dispatch_async(dispatch_get_main_queue(), { () -> Void in | |
completionHandler(image: image) | |
}) | |
}) | |
} | |
/* Creates a gradient image from a set of colors*/ | |
class func imageWithGradientColors(rect: CGRect, colors:CGColorRef..., completionHandler:(image:UIImage)->()) { | |
dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0), { () -> Void in | |
let maxWidth = max(rect.size.height,rect.size.width) | |
let squareFrame = CGRect(origin: rect.origin, size: CGSizeMake(maxWidth, maxWidth)) | |
UIGraphicsBeginImageContextWithOptions(squareFrame.size, false, UIScreen.mainScreen().scale) | |
// UIGraphicsBeginImageContext(squareFrame.size) | |
var gradient:CAGradientLayer? = CAGradientLayer() | |
gradient?.frame = squareFrame | |
gradient?.colors = colors | |
gradient?.renderInContext(UIGraphicsGetCurrentContext()!) | |
let image = UIGraphicsGetImageFromCurrentImageContext() | |
image.fixOrientation() | |
//let rotatedImage = UIImage(CGImage: image.CGImage!, scale: UIScreen.mainScreen().scale, orientation: UIImageOrientation.Up) | |
UIGraphicsEndImageContext() | |
gradient = nil | |
//return image | |
dispatch_async(dispatch_get_main_queue(), { () -> Void in | |
completionHandler(image: image) | |
}) | |
}) | |
} | |
class func imageWithImage (source:UIImage, scaledToWidth imgWidth:CGFloat) -> UIImage { | |
let oldWidth = source.size.width | |
let scaleFactor = imgWidth / oldWidth | |
let newHeight = source.size.height * scaleFactor | |
let newWidth = oldWidth * scaleFactor | |
UIGraphicsBeginImageContext(CGSizeMake(newWidth, newHeight)) | |
source.drawInRect(CGRect(x: 0, y: 0, width: newWidth, height: newHeight)) | |
let newImage = UIGraphicsGetImageFromCurrentImageContext() | |
UIGraphicsEndImageContext() | |
return newImage | |
} | |
class func imageWithImage(source:UIImage, scaledToSize newSize:CGSize) -> UIImage? { | |
//guard newSize != CGSizeZero else { return UIImage() } | |
UIGraphicsBeginImageContextWithOptions(newSize, false, UIScreen.mainScreen().scale) | |
source.drawInRect(CGRect(x: 0, y: 0, width: newSize.width, height: newSize.height)) | |
let newImage = UIGraphicsGetImageFromCurrentImageContext() | |
UIGraphicsEndImageContext() | |
return newImage | |
} | |
func imageScaledToFitToSize (size:CGSize) -> UIImage { | |
let scaledRect = AVMakeRectWithAspectRatioInsideRect(self.size,CGRectMake(0, 0, size.width, size.height)) | |
UIGraphicsBeginImageContextWithOptions(size, false, UIScreen.mainScreen().scale) | |
self.drawInRect(scaledRect) | |
let scaledImage = UIGraphicsGetImageFromCurrentImageContext() | |
UIGraphicsEndImageContext() | |
return scaledImage | |
} | |
class func imageWithText (text: String, fontname:String, fontSize:CGFloat, completionHandler:(image:UIImage)->()) { | |
dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0), { () -> Void in | |
// set the font type and size | |
let font = UIFont(name: fontname, size: fontSize) | |
let attr = [NSFontAttributeName:font!] | |
let size = (text as NSString).sizeWithAttributes( attr ) | |
UIGraphicsBeginImageContextWithOptions(size, false, UIScreen.mainScreen().scale) | |
// optional: add a shadow, to avoid clipping the shadow you should make the context size bigger | |
let ctx:CGContextRef = UIGraphicsGetCurrentContext()! | |
//Set stroke color to black - http://www.w3.org/TR/REC-CSS2/syndata.html#value- def-color. | |
CGContextSetRGBStrokeColor(ctx, 0.0, 0.0, 0.0, 1.0); | |
//Shadow color can also be changed | |
//CGContextSetShadowWithColor(ctx, size, CGFloat (0.5), UIColor.grayColor().CGColor) | |
//draw text in context at the origin | |
(text as NSString).drawAtPoint( CGPointZero, withAttributes: attr ) | |
//Other advanced options if you want to draw in a rect | |
//let rect = CGRectMake(0, 0, image.size.width, image.size.height) | |
//CGContextStrokeRect(ctx, rect) | |
//(text as NSString).drawInRect(<#T##rect: CGRect##CGRect#>, withAttributes: <#T##[String : AnyObject]?#>) | |
//(text as NSString).drawWithRect(<#T##rect: CGRect##CGRect#>, options: <#T##NSStringDrawingOptions#>, attributes: <#T##[String : AnyObject]?#>, context: <#T##NSStringDrawingContext?#>) | |
let testImg = UIGraphicsGetImageFromCurrentImageContext(); | |
UIGraphicsEndImageContext(); | |
//return testImg | |
dispatch_async(dispatch_get_main_queue(), { () -> Void in | |
completionHandler(image: testImg!) | |
}) | |
}) | |
} | |
class func collageImage (rect:CGRect, images:[UIImage],maxImageCount:Int, completionHandler:(image:UIImage)->()) { | |
guard rect != CGRectZero else { return } | |
dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INTERACTIVE, 0), { () -> Void in | |
let maxImagesPerRow = maxImageCount | |
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 | |
UIGraphicsBeginImageContextWithOptions(rect.size, false, UIScreen.mainScreen().scale) | |
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) | |
} | |
//draw in rect ~ scales to width | |
// let i = UIImage.imageWithImage(img, scaledToWidth: smallRect.size.width) | |
//if img != nil { | |
if let i = UIImage.imageWithImage(img, scaledToSize: smallRect.size) { | |
i.drawInRect(smallRect) | |
} | |
//} | |
// produces correct scale but leaves horizontal gap btw each image img.imageScaledToFitToSize(smallRect.size).drawInRect(smallRect) | |
} | |
let outputImage = UIGraphicsGetImageFromCurrentImageContext(); | |
UIGraphicsEndImageContext(); | |
//return outputImage | |
if outputImage != nil { | |
completionHandler(image: outputImage) | |
} | |
// dispatch_async(dispatch_get_main_queue(), { () -> Void in | |
// | |
// }) | |
}) | |
} | |
class func collageImage (rect:CGRect, images:[UIImage],completionHandler:(image:UIImage)->()) { | |
dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INTERACTIVE, 0), { () -> Void in | |
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 | |
UIGraphicsBeginImageContextWithOptions(rect.size, false, UIScreen.mainScreen().scale) | |
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) | |
} | |
//draw in rect ~ scales to width | |
// let i = UIImage.imageWithImage(img, scaledToWidth: smallRect.size.width) | |
//if img != nil { | |
if let i = UIImage.imageWithImage(img, scaledToSize: smallRect.size) { | |
i.drawInRect(smallRect) | |
} | |
//} | |
// produces correct scale but leaves horizontal gap btw each image img.imageScaledToFitToSize(smallRect.size).drawInRect(smallRect) | |
} | |
let outputImage = UIGraphicsGetImageFromCurrentImageContext(); | |
UIGraphicsEndImageContext(); | |
//return outputImage | |
dispatch_async(dispatch_get_main_queue(), { () -> Void in | |
if outputImage != nil { | |
completionHandler(image: outputImage) | |
} | |
}) | |
}) | |
} | |
func rotateImage(image: UIImage) -> UIImage { | |
if (image.imageOrientation == UIImageOrientation.Up ) { | |
return image | |
} | |
UIGraphicsBeginImageContext(image.size) | |
image.drawInRect(CGRect(origin: CGPoint.zero, size: image.size)) | |
let copy = UIGraphicsGetImageFromCurrentImageContext() | |
UIGraphicsEndImageContext() | |
return copy | |
} | |
class func rotateImage(src: UIImage, radian:CGFloat, completionHandler:(image:UIImage)->()) | |
{ | |
dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0), { () -> Void in | |
// Calculate the size of the rotated view's containing box for our drawing space | |
let rotatedViewBox = UIView(frame: CGRectMake(0,0, src.size.width, src.size.height)) | |
let t: CGAffineTransform = CGAffineTransformMakeRotation(radian) | |
rotatedViewBox.transform = t | |
let rotatedSize = rotatedViewBox.frame.size | |
// Create the bitmap context | |
UIGraphicsBeginImageContext(rotatedSize) | |
let bitmap:CGContextRef = UIGraphicsGetCurrentContext()! | |
// Move the origin to the middle of the image so we will rotate and scale around the center. | |
CGContextTranslateCTM(bitmap, rotatedSize.width/2, rotatedSize.height/2); | |
// Rotate the image context | |
CGContextRotateCTM(bitmap, radian); | |
// Now, draw the rotated/scaled image into the context | |
CGContextScaleCTM(bitmap, 1.0, -1.0); | |
CGContextDrawImage(bitmap, CGRectMake(-src.size.width / 2, -src.size.height / 2, src.size.width, src.size.height), src.CGImage) | |
let newImage = UIGraphicsGetImageFromCurrentImageContext() | |
UIGraphicsEndImageContext() | |
dispatch_async(dispatch_get_main_queue(), { () -> Void in | |
completionHandler(image: newImage!) | |
}) | |
}) | |
} | |
func thumbnailForVideoAssetURL (url:NSURL, completionHandler:(image:UIImage, imageData:NSData)->()){ | |
dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INTERACTIVE, 0), { () -> Void in | |
let asset = AVURLAsset(URL: url) | |
let generator = AVAssetImageGenerator(asset: asset) | |
generator.appliesPreferredTrackTransform = true | |
var imgRef: CGImageRef? = nil | |
let time = CMTimeMake(1, 60) | |
do { | |
imgRef = try generator.copyCGImageAtTime(time, actualTime: UnsafeMutablePointer<CMTime>()) | |
} catch let e as NSError { | |
print( e.localizedDescription ) | |
} | |
if imgRef != nil { | |
let img = UIImage(CGImage: imgRef!) | |
dispatch_async(dispatch_get_main_queue(), { () -> Void in | |
completionHandler(image:img, imageData: UIImageJPEGRepresentation(img, 1.0)!) | |
}) | |
} | |
}) | |
} | |
/* | |
usage: | |
image.resize(CGSizeMake(150, 150), completionHandler: { [weak self](resizedImage, data) -> () in | |
let image = resizedImage | |
self?.imageView.image = image | |
self?.viewModel.imageData = data | |
})*/ | |
public func resize(size:CGSize, completionHandler:(resizedImage:UIImage, data:NSData)->()) { | |
dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0), { () -> Void in | |
let newSize:CGSize = size | |
var ratio:CGFloat = 0 | |
if newSize.width > newSize.height { | |
ratio = 44.0 / newSize.width | |
} else { | |
ratio = 44.0 / newSize.height | |
} | |
let rect = CGRectMake(0, 0, ratio * newSize.width, ratio * newSize.height) | |
UIGraphicsBeginImageContextWithOptions(newSize, true, UIScreen.mainScreen().scale) | |
self.drawInRect(rect) | |
let newImage = UIGraphicsGetImageFromCurrentImageContext() | |
newImage.resizableImageWithCapInsets(UIEdgeInsets(top: 0.5, left: 0.5, bottom: 0.5, right: 0.5)) | |
UIGraphicsEndImageContext() | |
let imageData = UIImageJPEGRepresentation(newImage, 0.5) | |
dispatch_async(dispatch_get_main_queue(), { () -> Void in | |
completionHandler(resizedImage: newImage, data:imageData!) | |
}) | |
}) | |
} | |
func thumbnailForImage(originalImage:UIImage, destinationSize:CGSize, completionHandler:(thumbnailImage:UIImage, thumbnailData:NSData)->()) { | |
dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0), { () -> Void in | |
UIGraphicsBeginImageContext(destinationSize) | |
originalImage.drawInRect(CGRectMake(0, 0, destinationSize.width, destinationSize.height)) | |
let newImage = UIGraphicsGetImageFromCurrentImageContext() | |
UIGraphicsEndImageContext() | |
let imageData = UIImageJPEGRepresentation(newImage, 0.2) | |
dispatch_async(dispatch_get_main_queue(), { () -> Void in | |
completionHandler(thumbnailImage: newImage, thumbnailData: imageData!) | |
}) | |
}) | |
} | |
func thumbnailForImageAtURL(url:NSURL, destinationSize:CGSize,completionHandler:(thumbnailImage:UIImage, thumbnailData:NSData)->()) { | |
dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0), { () -> Void in | |
let originalImage = UIImage( contentsOfFile: url.absoluteString ) | |
UIGraphicsBeginImageContext(destinationSize) | |
originalImage?.drawInRect(CGRectMake(0, 0, destinationSize.width, destinationSize.height)) | |
let newImage = UIGraphicsGetImageFromCurrentImageContext() | |
UIGraphicsEndImageContext() | |
let imageData = UIImageJPEGRepresentation(newImage, 0.2) | |
dispatch_async(dispatch_get_main_queue(), { () -> Void in | |
completionHandler(thumbnailImage: newImage, thumbnailData: imageData!) | |
}) | |
}) | |
} | |
/* | |
Generates an NSNotification message: MNGImageEvents.ImageSavedToAssetsLibrary containing the assetURL object of the image saved to the directory or MNGImageEvents.ImageSavedToAssetsLibrary containing an NSError object in the event of a failure will saving to the Asset Library | |
*/ | |
// @available(iOS 8, *) | |
// @warn_unqualified_access | |
// func imageSaveToAssetLibrary (image:UIImage, completionHandler:(url:NSURL)->()) { | |
// | |
// dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0), { () -> Void in | |
// | |
// | |
// var alOrientation:ALAssetOrientation | |
// | |
// switch (UIDevice.currentDevice().orientation) { | |
// case UIDeviceOrientation.PortraitUpsideDown: | |
// alOrientation = ALAssetOrientation.Left//2 insted of ALAssetOrientationDown; | |
// break | |
// case UIDeviceOrientation.LandscapeLeft: | |
// alOrientation = ALAssetOrientation.Up //0 instead of ALAssetOrientationLeft; | |
// break | |
// case UIDeviceOrientation.LandscapeRight: | |
// alOrientation = ALAssetOrientation.Down; //1 instead of ALAssetOrientationRight; | |
// break | |
// case UIDeviceOrientation.Portrait: fallthrough | |
// default: | |
// alOrientation = ALAssetOrientation.Right //3 instead ofALAssetOrientationUp; | |
// break | |
// } | |
// | |
// let library = ALAssetsLibrary() | |
// library.writeImageToSavedPhotosAlbum(image.CGImage, orientation: alOrientation, completionBlock: { (assetURL, error) -> Void in | |
// | |
// if error == nil { | |
// //set the assetURL | |
// dispatch_async(dispatch_get_main_queue(), { () -> Void in | |
// //output = assetURL | |
// completionHandler(url: assetURL) | |
// }) | |
// | |
// } else { | |
// print ("Error: \(error.localizedDescription)") | |
// } | |
// }) | |
// }) | |
// } | |
func imageSaveToPhotoLibrary (image:UIImage, toAlbum album:PHAssetCollection,completionHandler:(image:UIImage, assetURL:NSURL)->()) { | |
dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0), { () -> Void in | |
var assetPlaceHolder:PHObjectPlaceholder? = nil | |
PHPhotoLibrary.sharedPhotoLibrary().performChanges({ () -> Void in | |
// Request creating an asset from the image. | |
let createAssetRequest = PHAssetChangeRequest.creationRequestForAssetFromImage(image) | |
// Request editing the album. | |
let albumChangeRequest = PHAssetCollectionChangeRequest(forAssetCollection: album) | |
// Get a placeholder for the new asset and add it to the album editing request. | |
assetPlaceHolder = createAssetRequest.placeholderForCreatedAsset! | |
albumChangeRequest?.addAssets([assetPlaceHolder!]) | |
}) { (success, error) -> Void in | |
// | |
if (success) { | |
//get the image details back from the Photo Library | |
let opts = PHFetchOptions() | |
opts.predicate = NSPredicate(format: "mediaType = %d", PHAssetMediaType.Image.rawValue) | |
let result = PHAsset.fetchAssetsWithLocalIdentifiers( [assetPlaceHolder!.localIdentifier], options: opts ) | |
let asset = result.firstObject as! PHAsset | |
let reqOpts = PHImageRequestOptions() | |
reqOpts.resizeMode = PHImageRequestOptionsResizeMode.Fast | |
let edtOpts = PHContentEditingInputRequestOptions() | |
edtOpts.networkAccessAllowed = true | |
var assetURL:NSURL? = nil | |
asset.requestContentEditingInputWithOptions(edtOpts, completionHandler: { (contentEditingInput, info) -> Void in | |
//assetURL complete | |
assetURL = contentEditingInput!.fullSizeImageURL! | |
}) | |
let pimManager = PHImageManager.defaultManager() | |
pimManager.requestImageForAsset(asset, targetSize: self.size, contentMode: PHImageContentMode.AspectFit, options: reqOpts, resultHandler: { (outputImage, info) -> Void in | |
//image retrieval complete | |
dispatch_async(dispatch_get_main_queue(), { () -> Void in | |
if assetURL != nil { | |
if outputImage != nil { | |
completionHandler(image: outputImage!, assetURL: assetURL!) | |
} | |
} | |
}) | |
}) | |
} | |
if (error != nil) { | |
print("Error description: \(error?.localizedDescription)") | |
} | |
} | |
}) | |
} | |
func assetSaveToDocumentSubfolder (asset:AVAsset, folderURL:NSURL,completionHandler:(assetURL:NSURL)->()){ | |
} | |
func phAssetSaveToDocumentSubfolder (asset:PHAsset, folderURL:NSURL,completionHandler:(assetURL:NSURL)->()){ | |
} | |
func imageSaveToDocumentSubfolder (image:UIImage, folderURL:NSURL,completionHandler:(assetURL:NSURL)->()){ | |
} | |
} | |
extension CIImage { | |
func mng_jpegRepresentationWithCompressionQuality(compressionQuality: CGFloat) -> NSData { | |
var ciContext: CIContext? = nil | |
if !(ciContext != nil) { | |
let eaglContext: EAGLContext = EAGLContext(API: EAGLRenderingAPI.OpenGLES2) | |
ciContext = CIContext(EAGLContext: eaglContext) | |
} | |
let outputImageRef: CGImageRef = ciContext!.createCGImage(self, fromRect: self.extent) | |
let uiImage: UIImage = UIImage(CGImage: outputImageRef, scale: 1.0, orientation: UIImageOrientation.Up) | |
let jpegRepresentation: NSData = UIImageJPEGRepresentation(uiImage, compressionQuality)! | |
return jpegRepresentation | |
} | |
/// Captures single still image as `jpegStillImageNSDataRepresentation` along with separate mutable metadata dictionary with provided values. | |
func captureSingleStillImage(completionHandler handler: ((image:UIImage, metadata:NSDictionary) -> Void)) { | |
let sessionQueue = dispatch_get_global_queue(QOS_CLASS_BACKGROUND, 0) | |
dispatch_async(sessionQueue) { () -> Void in | |
let stillCameraOutput = AVCaptureStillImageOutput() | |
let connection = stillCameraOutput.connectionWithMediaType(AVMediaTypeVideo) | |
connection.videoOrientation = AVCaptureVideoOrientation(rawValue: UIDevice.currentDevice().orientation.rawValue)! | |
stillCameraOutput.captureStillImageAsynchronouslyFromConnection(connection) { | |
(imageDataSampleBuffer, error) -> Void in | |
let imageData = AVCaptureStillImageOutput.jpegStillImageNSDataRepresentation(imageDataSampleBuffer) | |
let metadata = CMCopyDictionaryOfAttachments(nil, imageDataSampleBuffer, CMAttachmentMode(kCMAttachmentMode_ShouldPropagate))! as CFDictionaryRef | |
let metadataMutable = CFDictionaryCreateMutableCopy(nil, 0, metadata) | |
let utcDate = "\(NSDate())" | |
let cfUTCDate = CFStringCreateCopy(nil, utcDate) | |
CFDictionarySetValue(metadataMutable!, unsafeAddressOf(kCGImagePropertyGPSDateStamp), unsafeAddressOf(cfUTCDate)) | |
//var metaAltitude = self.locManager.location?.altitude | |
//let cfMetaAltitude = CFNumberCreate(nil, CFNumberType.DoubleType, &metaAltitude)! | |
//CFDictionarySetValue(self.metadataMutable!, unsafeAddressOf(kCGImagePropertyGPSAltitude), unsafeAddressOf(cfMetaAltitude)) | |
//var metaLatitude = self.locManager.location?.coordinate.latitude | |
//let cfMetaLatitude = CFNumberCreate(nil, CFNumberType.DoubleType, &metaLatitude)! | |
//CFDictionarySetValue(self.metadataMutable!, unsafeAddressOf(kCGImagePropertyGPSLatitude), unsafeAddressOf(cfMetaLatitude)) | |
//var metaLongitude = self.locManager.location?.coordinate.longitude | |
//let cfMetaLongitude = CFNumberCreate(nil, CFNumberType.DoubleType, &metaLongitude)! | |
//CFDictionarySetValue(self.metadataMutable!, unsafeAddressOf(kCGImagePropertyGPSLongitude), unsafeAddressOf(cfMetaLongitude)) | |
//let geoXYZ = "\(self.locManager.heading!.x), \(self.locManager.heading!.y), \(self.locManager.heading!.z)" | |
//let cfGeoXYZ = CFStringCreateCopy(nil, geoXYZ) | |
//CFDictionarySetValue(self.metadataMutable!, unsafeAddressOf(kCGImagePropertyGPSMapDatum), unsafeAddressOf(cfGeoXYZ)) | |
if let image = UIImage(data: imageData) { | |
dispatch_async(dispatch_get_main_queue()) { () -> Void in | |
handler(image: image, metadata: metadataMutable!) | |
} | |
} | |
else { | |
NSLog("error while capturing still image: \(error)") | |
} | |
} | |
} | |
} | |
func createThumbnailFromData (data:NSData, var imageSize:Int) -> CGImageRef?{ | |
var myThumbnailImage: CGImageRef? = nil | |
var myImageSource: CGImageSourceRef? = nil | |
var myOptions: CFDictionaryRef? = nil | |
var myKeys = [CFStringRef] ()//= [kCGImageSourceCreateThumbnailWithTransform, kCGImageSourceCreateThumbnailFromImageIfAbsent, kCGImageSourceThumbnailMaxPixelSize, kCGImageSourceCreateThumbnailFromImageAlways] | |
let keysPointer = UnsafeMutablePointer<UnsafePointer<Void>>.alloc(1) | |
keysPointer.initialize(myKeys) | |
var myValues = [CFTypeRef]()// = [kCFBooleanTrue, kCFBooleanTrue, kCFBooleanTrue, kCFBooleanTrue] | |
let valuesPointer = UnsafeMutablePointer<UnsafePointer<Void>>.alloc(1) | |
valuesPointer.initialize(myValues) | |
let dictionayKeyCB = UnsafePointer<CFDictionaryKeyCallBacks>() | |
let valueKeyCB = UnsafePointer<CFDictionaryValueCallBacks>() | |
var thumbnailSize: CFNumberRef | |
// Create an image source from NSData; no options. | |
myImageSource = CGImageSourceCreateWithData(data, nil)! | |
if myImageSource == nil { | |
print("Source is nil") | |
//var NULL: source is | |
return nil | |
} | |
thumbnailSize = CFNumberCreate(nil, CFNumberType.IntType, &imageSize) | |
myKeys[0] = kCGImageSourceCreateThumbnailWithTransform as String | |
myValues[0] = kCFBooleanTrue | |
myKeys[1] = kCGImageSourceCreateThumbnailFromImageIfAbsent as String | |
myValues[1] = kCFBooleanTrue | |
myKeys[2] = kCGImageSourceThumbnailMaxPixelSize as String | |
myValues[2] = thumbnailSize | |
myOptions = CFDictionaryCreate(nil, keysPointer, valuesPointer, 2, dictionayKeyCB , valueKeyCB) | |
myThumbnailImage = CGImageSourceCreateThumbnailAtIndex(myImageSource!, 0, myOptions) | |
if myThumbnailImage == nil { | |
print("source image not created from image") | |
//stderrThumbnail | |
//var source: image not created from image | |
return nil | |
} | |
return myThumbnailImage | |
} | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// MNGImageExtensions.swift | |
// | |
// | |
// Created by Tommie Carter on 7/2/15. | |
// Copyright © 2015 MING Technology. All rights reserved. | |
// | |
// | |
// Sample usage: Connect an UIImageView on a storyboard to an IBOutlet as shown - Should also work with custom fonts | |
// @IBOutlet weak var message: UIImageView! { | |
// didSet { | |
// if message != nil { | |
// message.image = UIImage.imageFromText("Share", fontname: "Chalkduster", fontSize: CGFloat(60.0)) | |
// } | |
// } | |
//} | |
import UIKit | |
extension UIImage { | |
class func imageFromText (text: String, fontname:String, fontSize:CGFloat) -> UIImage? { | |
// set the font type and size | |
let font = UIFont(name: fontname, size: fontSize) | |
let attr = [NSFontAttributeName:font!] | |
let size = (text as NSString).sizeWithAttributes( attr ) | |
UIGraphicsBeginImageContextWithOptions(size, false, UIScreen.mainScreen().scale) | |
// optional: add a shadow, to avoid clipping the shadow you should make the context size bigger | |
let ctx:CGContextRef = UIGraphicsGetCurrentContext() | |
//Set stroke color to black - http://www.w3.org/TR/REC-CSS2/syndata.html#value- def-color. | |
CGContextSetRGBStrokeColor(ctx, 0.0, 0.0, 0.0, 1.0); | |
//Shadow color can also be changed | |
//CGContextSetShadowWithColor(ctx, size, CGFloat (0.5), UIColor.grayColor().CGColor) | |
//draw text in context at the origin | |
(text as NSString).drawAtPoint( CGPointZero, withAttributes: attr ) | |
//Other advanced options if you want to draw in a rect | |
//let rect = CGRectMake(0, 0, image.size.width, image.size.height) | |
//CGContextStrokeRect(ctx, rect) | |
//(text as NSString).drawInRect(<#T##rect: CGRect##CGRect#>, withAttributes: <#T##[String : AnyObject]?#>) | |
//(text as NSString).drawWithRect(<#T##rect: CGRect##CGRect#>, options: <#T##NSStringDrawingOptions#>, attributes: <#T##[String : AnyObject]?#>, context: <#T##NSStringDrawingContext?#>) | |
let testImg = UIGraphicsGetImageFromCurrentImageContext(); | |
UIGraphicsEndImageContext(); | |
return testImg | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment