Return an updated UIImageView

SayI have a function that will receive a UIImage as an argument, perform the logic inside it and then return it updated
So I came up with something like this:

  func processImage(image: UIImage?) -> UIImage? {
         if let image = image, let cgImage = image.cgImage {
            let width = cgImage.width
            let height = cgImage.height

            let colorSpace = CGColorSpaceCreateDeviceRGB()
            let bitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.premultipliedLast.rawValue)

            if let context = CGContext(data: nil,
                                       width: width,
                                       height: height,
                                       bitsPerComponent: 8,
                                       bytesPerRow: 4 * width,
                                       space: colorSpace,
                                       bitmapInfo: bitmapInfo.rawValue) {

                context.draw(cgImage, in: CGRect(x: 0, y: 0, width: CGFloat(width), height: CGFloat(height)))

                if let data = context.data {
                    let buffer = data.bindMemory(to: UInt8.self, capacity: width * height * 4)

                    for i in 0..<(width * height) {
                        let pixelIndex = i * 4
                        let red = buffer[pixelIndex]
                        let green = buffer[pixelIndex + 1]
                        let blue = buffer[pixelIndex + 2]

                        if isSystemGrayPixel(red: red, green: green, blue: blue) {
                            // Convert systemGray to systemPink
                            buffer[pixelIndex] = 255  // R component
                            buffer[pixelIndex + 1] = 182  // G component
                            buffer[pixelIndex + 2] = 193  // B component
                        }
                    }

                    if let modifiedCGImage = context.makeImage() {
                        let processedImage = UIImage(cgImage: modifiedCGImage)
                        return processedImage
                    }
                }
            }
        }

        return image
    }

insde it I have called a helper function that will conditionally check if it contains .systemGrey and if so than change it as I

    func isSystemGrayPixel(red: UInt8, green: UInt8, blue: UInt8) -> Bool {
        let systemGrayColor = UIColor.systemBlue
        let ciSystemGrayColor = CIColor(color: systemGrayColor)

       
        let tolerance: CGFloat = 10.0 / 255.0

        let redDiff = abs(ciSystemGrayColor.red - CGFloat(red) / 255.0)
        let greenDiff = abs(ciSystemGrayColor.green - CGFloat(green) / 255.0)
        let blueDiff = abs(ciSystemGrayColor.blue - CGFloat(blue) / 255.0)

        return redDiff <= tolerance && greenDiff <= tolerance && blueDiff <= tolerance
    }

When I try to save it into a saveCanvas I will show in the console that the entry is saved but when i try to retrieve it later I will get nil This is my saveCanvas to serve as a reference


  @objc func saveCanvas(_ sender: Any)   {
        guard let canvas = Canvas(name: "", canvas: mainImageView, numOfPages: 0) else {
            return
        }
     
        var savedImageView2 =  UIImageView()
        savedImageView2.image = mainImageView.image?.copy() as? UIImage
        
        let updatedImage = processImage(image: savedImageView2.image)
        
        canvas.canvas.image = updatedImage
      
        // array that stores UIimageView gobally defined
        canvasArray.append(canvas)
        
        if canvasArray.count > 0 {
            canvasArray.forEach{ canvas in
                print("\(canvas.canvas == savedImageView )")

            print("clicked button \( canvasArray) ")
                      
            }
        }
    }

I am expecting to retrieve each iteration of canvasArray when i call it later in another function(which worked fine before I created the processImage function) . Like I said the purpose of processImage is to check if my UIImage contains .systemGrey and i so returned updated as I defined inside my isSystemGrayPixel function. Is there anything you might consider I do different rather do in my processImage to make it work as expected?

Does this help to solve your problem?

https://codermite.com/t/issue-with-saving-processed-images-in-swift-uiimage-becomes-nil

As Paradigm777 explained, problem is likely in

canvas.canvas.image = updatedImage

You copy the reference (pointer) of the UIImage (not UIImageView) , not the content. Hence the advice to use copy.

However, could you show complete code so we can try to reproduce ?

Note: a bit confusing (in naming) to have a canvas property inside canvas…

Return an updated UIImageView
 
 
Q