Created
April 10, 2017 14:23
-
-
Save Lucien/ccb81ef77daed9f51396695c98fea01d to your computer and use it in GitHub Desktop.
CGImage operations
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
import UIKit | |
extension CGImage { | |
func increaseWidthToMultipleOfSeventeen(completion: @escaping (CGImage?) -> (Void)) { | |
DispatchQueue.global(qos: .background).async { [weak self] in | |
guard let strongSelf = self else { | |
DispatchQueue.main.async { | |
completion(nil) | |
} | |
return | |
} | |
let aspectRatio = Float(strongSelf.height) / Float(strongSelf.width) | |
let newWidth = ceilf(Float(strongSelf.width) / 17) * 17 | |
let newHeight = ceilf(newWidth * aspectRatio) | |
guard let colorSpace = strongSelf.colorSpace else { | |
DispatchQueue.main.async { | |
completion(nil) | |
} | |
return | |
} | |
let context = CGContext(data: nil, | |
width: Int(newWidth), | |
height: Int(newHeight), | |
bitsPerComponent: strongSelf.bitsPerComponent, | |
bytesPerRow: 0, | |
space: colorSpace, | |
bitmapInfo: strongSelf.bitmapInfo.rawValue) | |
let rect = CGRect(origin: CGPoint.zero, | |
size: CGSize(width: Int(newWidth), | |
height: Int(newHeight))) | |
context?.interpolationQuality = CGInterpolationQuality.high | |
context?.setFillColor(UIColor.white.cgColor) | |
context?.fill(rect) | |
context?.draw(strongSelf, in: rect) | |
let image = context?.makeImage() | |
DispatchQueue.main.async { | |
completion(image) | |
} | |
} | |
} | |
func transformToCGCoordinates() -> CGImage? { | |
guard let colorSpace = colorSpace else { return nil } | |
let context = CGContext(data: nil, | |
width: width, | |
height: height, | |
bitsPerComponent: bitsPerComponent, | |
bytesPerRow: bytesPerRow, | |
space: colorSpace, | |
bitmapInfo: bitmapInfo.rawValue) | |
let halfWidth = 0.5 * CGFloat(width) | |
let halfHeight = 0.5 * CGFloat(height) | |
let rect = CGRect(origin: CGPoint(x: -halfWidth, y: -halfHeight), | |
size: CGSize(width: width, height: height)) | |
context?.translateBy(x: halfWidth, y: halfHeight) | |
context?.rotate(by: CGFloat.pi) | |
context?.scaleBy(x: -1.0, y: 1.0) | |
context?.interpolationQuality = CGInterpolationQuality.high | |
context?.setFillColor(UIColor.white.cgColor) | |
context?.fill(rect) | |
context?.draw(self, in: rect) | |
return context?.makeImage() | |
} | |
static func optimizedImageForOCR(inputImage: CGImage, | |
spacing: Int = 10, | |
charCount: Int = 17, | |
border: UIOffset = UIOffset(horizontal: 10, vertical: 10), | |
completion: @escaping (UIImage?) -> (Void)) { | |
DispatchQueue.global(qos: .background).async { | |
let charWidth = lroundf(Float(inputImage.width) / Float(charCount)) | |
let totalWidth = inputImage.width + ((charCount-1) * spacing) | |
let finalSize = CGSize(width: totalWidth + (2 * Int(border.horizontal)), | |
height: inputImage.height + (2 * Int(border.vertical))) | |
let finalRect = CGRect(origin: CGPoint.zero, size: finalSize) | |
UIGraphicsBeginImageContextWithOptions(finalSize, true, 0.0) | |
let context = UIGraphicsGetCurrentContext() | |
context?.setFillColor(UIColor.white.cgColor) | |
context?.fill(finalRect) | |
// 1 - get array of images of each char | |
var charImages: [CGImage] = [] | |
for i in 0...charCount-1 { | |
let maxX = charWidth * (i + 1) | |
let cropRect = CGRect(x: maxX - charWidth, y: 0, width: charWidth, height: inputImage.height) | |
if let charImage = inputImage.cropping(to: cropRect) { | |
if let finalCharImage = charImage.transformToCGCoordinates() { | |
charImages.append(finalCharImage) | |
} else { | |
DispatchQueue.main.async { | |
completion(nil) | |
} | |
return | |
} | |
} | |
} | |
// 2 - draw each image on the new position (considering spacing) | |
var i = 0 | |
for charImage in charImages { | |
var x = Int(border.horizontal) + (i * (charWidth + spacing)) | |
if i == 0 { | |
x = Int(border.horizontal) | |
} | |
let newCharPosition = CGRect(x: x, | |
y: Int(border.vertical), | |
width: charWidth, | |
height: inputImage.height) | |
context?.draw(charImage, in: newCharPosition) | |
i += 1 | |
} | |
let imageWithoutBorder: CGImage? = context?.makeImage() | |
UIGraphicsEndImageContext() | |
let uiImage = UIImage(cgImage: imageWithoutBorder!, scale: 1.0, orientation: UIImageOrientation.up) | |
DispatchQueue.main.async { | |
completion(uiImage) | |
} | |
} | |
} | |
func addBorder() -> CGImage? { | |
let spacing: Int = 20 | |
let finalSize = CGSize(width: width + (2 * spacing), | |
height: height + (2 * spacing)) | |
UIGraphicsBeginImageContextWithOptions(finalSize, | |
true, | |
0.0) | |
let context = UIGraphicsGetCurrentContext() | |
context?.setFillColor(UIColor.white.cgColor) | |
context?.fill(CGRect(origin: CGPoint.zero, size: finalSize)) | |
context?.draw(self, in: CGRect(x: spacing, | |
y: spacing, | |
width: width, | |
height: height)) | |
let resultImage = context?.makeImage() | |
UIGraphicsEndImageContext() | |
return resultImage | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment