swiftimage-processingcgcontextcgcontextdrawimage

Convert raw image data to jpeg in swift


I am trying to convert the raw image data to jpeg in swift. But unfortunately, the jpeg image created is skewed. Please find below the code used for the conversion.

let rawPtr = (rawImgData as NSData).bytes
let mutableRawPtr = UnsafeMutableRawPointer.init(mutating: rawPtr)
let context = CGContext.init(data: mutableRawPtr,
                             width: 750,
                             height: 1334,
                             bitsPerComponent: 32,
                             bytesPerRow: (8 * 750)/8,
                             space: CGColorSpaceCreateDeviceRGB(),
                             bitmapInfo: CGImageAlphaInfo.premultipliedLast.rawValue())
let imageRef = CGContext.makeImage(context!)
let imageRep = NSBitmapImageRep(cgImage: imageRef()!)
let finalData = imageRep.representation(using: .jpeg,
                                        properties: [NSBitmapImageRep.PropertyKey.compressionFactor : 0.5])

Here's the converted jpeg image

Converted Image

Any help or pointers would be greatly appreciated. Thanks in advance!


Solution

  • Finally figured out the answer

    var width:size_t?
    var height:size_t?
    let bitsPerComponent:size_t = 8
    var bytesPerRow:size_t?
    var bitmapInfo: UInt32
    if #available(OSX 10.12, *) {
        bitmapInfo = UInt32(CGImageAlphaInfo.premultipliedFirst.rawValue) | UInt32(CGImageByteOrderInfo.order32Little.rawValue)
    } else {
        bitmapInfo = UInt32(CGImageAlphaInfo.premultipliedFirst.rawValue)
    }
    let colorSpace = CGColorSpaceCreateDeviceRGB()
    
    do {
        let streamAttributesFuture = self.bitmapStream?.streamAttributes()
        streamAttributesFuture?.onQueue(.main, notifyOfCompletion: { (streamAttributesFut) in
    
        })
        try streamAttributesFuture?.await()
        let dict = streamAttributesFuture?.result
        width = (dict?.attributes["width"] as! Int)
        height = (dict?.attributes["height"] as! Int)
        bytesPerRow = (dict?.attributes["row_size"] as! Int)
    
    } catch let frameError{
        print("frame error = \(frameError)")
        return
    }
    
    let rawPtr = (data as NSData).bytes
    let mutableRawPtr = UnsafeMutableRawPointer.init(mutating: rawPtr)
    let context = CGContext.init(data: mutableRawPtr, width: width!, height: height!, bitsPerComponent: bitsPerComponent, bytesPerRow: bytesPerRow!, space: colorSpace, bitmapInfo: bitmapInfo)
    if context == nil {
        return
    }
    
    let imageRef = context?.makeImage()
    
    let scaledWidth = Int(Double(width!) / 1.5)
    let scaledHeight = Int(Double(height!) / 1.5)
    
    let resizeCtx = CGContext.init(data: nil, width: scaledWidth, height: scaledHeight, bitsPerComponent: bitsPerComponent, bytesPerRow: bytesPerRow!, space: colorSpace, bitmapInfo: bitmapInfo)
    resizeCtx?.draw(imageRef!, in: CGRect(x: 0, y: 0, width: scaledWidth, height: scaledHeight))
    
    resizeCtx?.interpolationQuality = .low
    
    let resizedImgRef = resizeCtx?.makeImage()
    let imageRep = NSBitmapImageRep(cgImage: resizedImgRef!)
    
    let finalData = imageRep.representation(using: .jpeg, properties: [NSBitmapImageRep.PropertyKey.compressionFactor : compression])