Skip to content

Instantly share code, notes, and snippets.

@palmerc
Created February 2, 2016 11:19
Show Gist options
  • Select an option

  • Save palmerc/c9db092e756c7d614c45 to your computer and use it in GitHub Desktop.

Select an option

Save palmerc/c9db092e756c7d614c45 to your computer and use it in GitHub Desktop.
import UIKit
public struct Pixel {
public var value: UInt32
public var red: UInt8 {
get {
return UInt8(value & 0xFF)
}
set {
value = UInt32(newValue) | (value & 0xFFFFFF00)
}
}
public var green: UInt8 {
get {
return UInt8((value >> 8) & 0xFF)
}
set {
value = (UInt32(newValue) << 8) | (value & 0xFFFF00FF)
}
}
public var blue: UInt8 {
get {
return UInt8((value >> 16) & 0xFF)
}
set {
value = (UInt32(newValue) << 16) | (value & 0xFF00FFFF)
}
}
public var alpha: UInt8 {
get {
return UInt8((value >> 24) & 0xFF)
}
set {
value = (UInt32(newValue) << 24) | (value & 0x00FFFFFF)
}
}
}
public struct RGBAImage {
public var pixels: UnsafeMutableBufferPointer<Pixel>
public var width: Int
public var height: Int
public init?(image: UIImage) {
guard let cgImage = image.CGImage else { return nil }
// Redraw image for correct pixel format
let colorSpace = CGColorSpaceCreateDeviceRGB()
var bitmapInfo: UInt32 = CGBitmapInfo.ByteOrder32Big.rawValue
bitmapInfo |= CGImageAlphaInfo.PremultipliedLast.rawValue & CGBitmapInfo.AlphaInfoMask.rawValue
width = Int(image.size.width)
height = Int(image.size.height)
let bytesPerRow = width * 4
let imageData = UnsafeMutablePointer<Pixel>.alloc(width * height)
guard let imageContext = CGBitmapContextCreate(imageData, width, height, 8, bytesPerRow, colorSpace, bitmapInfo) else { return nil }
CGContextDrawImage(imageContext, CGRect(origin: CGPointZero, size: image.size), cgImage)
pixels = UnsafeMutableBufferPointer<Pixel>(start: imageData, count: width * height)
}
public func toUIImage() -> UIImage? {
let colorSpace = CGColorSpaceCreateDeviceRGB()
var bitmapInfo: UInt32 = CGBitmapInfo.ByteOrder32Big.rawValue
bitmapInfo |= CGImageAlphaInfo.PremultipliedLast.rawValue & CGBitmapInfo.AlphaInfoMask.rawValue
let bytesPerRow = width * 4
let imageContext = CGBitmapContextCreateWithData(pixels.baseAddress, width, height, 8, bytesPerRow, colorSpace, bitmapInfo, nil, nil)
guard let cgImage = CGBitmapContextCreateImage(imageContext) else {return nil}
let image = UIImage(CGImage: cgImage)
return image
}
}
@DuncanMC
Copy link
Copy Markdown

yuukiii submitted a fork that updated this code to recent versions of Swift. Would you mind merging his changes into yours? (I don't know if he submitted a PR from his fork or not. If not, you could always merge the changes yourself and credit him with the updates.

I did not see the fork and manually updated the code to Swift 5 syntax myself, which is tedious and a little tricky.

@palmerc
Copy link
Copy Markdown
Author

palmerc commented Jul 17, 2021

yuukiii submitted a fork that updated this code to recent versions of Swift. Would you mind merging his changes into yours? (I don't know if he submitted a PR from his fork or not. If not, you could always merge the changes yourself and credit him with the updates.

I did not see the fork and manually updated the code to Swift 5 syntax myself, which is tedious and a little tricky.

I would love a PR for this.

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