Skip to content

Instantly share code, notes, and snippets.

@palmerc
Last active April 15, 2024 03:35
Show Gist options
  • Save palmerc/a626b447c62f472dbae6 to your computer and use it in GitHub Desktop.
Save palmerc/a626b447c62f472dbae6 to your computer and use it in GitHub Desktop.
Roundtrip a UIImage to its raw pixel values and back to an image again
import UIKit
import CoreGraphics
func imageFromPixelValues(pixelValues: [UInt8]?, width: Int, height: Int) -> CGImage?
{
var imageRef: CGImage?
if pixelValues != nil {
let imageDataPointer = UnsafeMutablePointer<UInt8>(pixelValues!)
let colorSpaceRef = CGColorSpaceCreateDeviceGray()
let bitsPerComponent = 8
let bytesPerPixel = 1
let bitsPerPixel = bytesPerPixel * bitsPerComponent
let bytesPerRow = bytesPerPixel * width
let totalBytes = height * bytesPerRow
let bitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.None.rawValue)
.union(.ByteOrderDefault)
let providerRef = CGDataProviderCreateWithData(nil, imageDataPointer, totalBytes, nil)
imageRef = CGImageCreate(width,
height,
bitsPerComponent,
bitsPerPixel,
bytesPerRow,
colorSpaceRef,
bitmapInfo,
providerRef,
nil,
false,
CGColorRenderingIntent.RenderingIntentDefault)
}
return imageRef
}
func pixelValuesFromImage(imageRef: CGImage?) -> ([UInt8]?, width: Int, height: Int)
{
var width = 0
var height = 0
var pixelValues: [UInt8]?
if imageRef != nil {
width = CGImageGetWidth(imageRef)
height = CGImageGetHeight(imageRef)
let bitsPerComponent = CGImageGetBitsPerComponent(imageRef)
let bytesPerRow = CGImageGetBytesPerRow(imageRef)
let totalBytes = height * bytesPerRow
let colorSpace = CGColorSpaceCreateDeviceGray()
// let colorSpace = CGColorSpaceCreateDeviceRGB()
let buffer = [UInt8](count: totalBytes, repeatedValue: 0)
let mutablePointer = UnsafeMutablePointer<UInt8>(buffer)
let contextRef = CGBitmapContextCreate(mutablePointer, width, height, bitsPerComponent, bytesPerRow, colorSpace, 0)
CGContextDrawImage(contextRef, CGRectMake(0.0, 0.0, CGFloat(width), CGFloat(height)), imageRef)
let bufferPointer = UnsafeBufferPointer<UInt8>(start: mutablePointer, count: totalBytes)
pixelValues = Array<UInt8>(bufferPointer)
}
return (pixelValues, width, height)
}
var image: UIImage? = nil
let URL = NSBundle.mainBundle().URLForResource("zebra_5", withExtension: "tif")
let path = URL?.path
if (path != nil && NSFileManager().fileExistsAtPath(path!)) {
do {
try NSData(contentsOfURL: URL!, options: .DataReadingMappedIfSafe)
} catch let error as NSError {
print ("Error: \(error.localizedDescription)")
}
image = UIImage(contentsOfFile: path!)
}
let (intensityValues, width, height) = pixelValuesFromImage(image?.CGImage)
let roundTrippedImage = imageFromPixelValues(intensityValues, width: width, height: height)
let zebra = UIImage(CGImage: roundTrippedImage!)
@altagir
Copy link

altagir commented Apr 8, 2020

swift 3+

 let data: [UInt8] = [...]
 let image = UIImage(data: Data(bytes: data, count: data.count))

 guard let dataPng: Data = pngData() else { return [] }
 let finalData = [UInt8](dataPng)

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