I'm trying to get the color of a pixel from a UIImage, using a scroll view to scroll around an image imported from the photos library, or taken from the camera. Similar to this thread, here's the code I'm using to get the color of a certain pixel:
var image: UIImage?
private var imageData: CFData?
private var imageByteData: UnsafePointer<UInt8>?
private func processImageData() {
if let fixedOrientationImage = image!.fixOrientation() {
imageData = fixedOrientationImage.cgImage?.dataProvider?.data
imageByteData = CFDataGetBytePtr(imageData)
}
}
func getColorFromPixel(_ pixel: CGPoint) -> UIColor? {
let pixelByteLocation = ((Int(image!.size.width) * Int(pixel.y)) + Int(pixel.x)) * 4
if let data = imageByteData {
//fixOrientation() returns image in bgra format, not rgba
let b = CGFloat(data[pixelByteLocation])/255
let g = CGFloat(data[pixelByteLocation + 1])/255
let r = CGFloat(data[pixelByteLocation + 2])/255
let a = CGFloat(data[pixelByteLocation + 3])/255
return UIColor(red: r, green: g, blue: b, alpha: a)
} else {
return nil
}
}
I'm also fixing the image's orientation to be "up" before I set the imageData, so the CGImage has proper alignment. Similar to this answer, here's the code I am using to fix the image's orientation.
extension UIImage {
func fixOrientation() -> UIImage? {
UIGraphicsBeginImageContextWithOptions(size, false, scale)
self.draw(in: CGRect(x: 0, y: 0, width: size.width, height: size.height))
let normalizedImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return normalizedImage
}
}
When I scroll around my original image, the pixel color that is returned is correct for every image orientation, except for images taken with the front camera in portrait or portrait upside down. Everything else works, including front landscape and every orientation using the back camera.
When I scroll around the image, it looks like the location of the pixel color is what is wrong, not the color itself (so it's not a RGBA issue).
I also tried manually applying a transform to the UIImage, using this code, but I get the same results. Am I missing something?