-1

I have a function that can return the color of a pixel by points

extension CGImage {
func colors(at: CGPoint) -> UIColor {
    let colorSpace = CGColorSpaceCreateDeviceRGB()
    let bytesPerPixel = 4
    let bytesPerRow = bytesPerPixel * width
    let bitsPerComponent = 8
    let bitmapInfo: UInt32 = CGImageAlphaInfo.premultipliedLast.rawValue | CGBitmapInfo.byteOrder32Big.rawValue

    guard let context = CGContext(data: nil, width: width, height: height, bitsPerComponent: bitsPerComponent, bytesPerRow: bytesPerRow, space: colorSpace, bitmapInfo: bitmapInfo),
        let ptr = context.data?.assumingMemoryBound(to: UInt8.self) else {
            return .black
    }

    context.draw(self, in: CGRect(x: 0, y: 0, width: width, height: height))
    let i = bytesPerRow * Int(at.y) + bytesPerPixel * Int(at.x)
    
    let a = CGFloat(ptr[i + 3]) / 255.0
    let r = (CGFloat(ptr[i]) / a) / 255.0
    let g = (CGFloat(ptr[i + 1]) / a) / 255.0
    let b = (CGFloat(ptr[i + 2]) / a) / 255.0
    
        return UIColor(red: r, green: g, blue: b, alpha: a)
    }
}

I would like to write a function that could replace the color of a pixel by Point Can you please advise where to start?

  • 1
    Welcome to Stack Overflow. First step should always be searching. Head over to google (or your favorite search engine) and search for `swift replace color at point in uiimage` -- lots of results, and you'll almost certainly find your answer already out there. – DonMag Jul 13 '22 at 13:41
  • @DonMag Thanks, I looked but didn't find what I was looking for. – Chepelev Evgeniy Jul 13 '22 at 14:31
  • Well, you need to be a little more descriptive than *"I looked but didn't find what I was looking for"* ... the code in this answer (first match when searching): https://stackoverflow.com/questions/31661023/change-color-of-certain-pixels-in-a-uiimage works well for me when replacing all pixels of a specific color. What are you trying to do? Do you want to set one pixel to a specific color? If so, you can easily modify that code. Or, you could use `UIGraphicsImageRenderer`. But you need to show that you've tried something, and explain what *"didn't work for you"* – DonMag Jul 13 '22 at 15:09
  • @DonMag Yes, you need to change the color in the image by points, it will always be one point, for example CGPoint (x: 0, y: 0) before that, I wrote in Kotlin and it was made easier there, everything was done through the Bitmap in which there was a setColor method – Chepelev Evgeniy Jul 13 '22 at 15:14

1 Answers1

0

Depending on what all you want to do, this may or may not be the appropriate approach.

However, without additional information...

This func will set the pixel at atPoint to on onImage to color:

func setColor(color: UIColor, onImage: UIImage, atPoint: CGPoint) -> UIImage {
    let rndr = UIGraphicsImageRenderer(size: onImage.size)
    let newImg = rndr.image { ctx in
        onImage.draw(at: .zero)
        let r = CGRect(origin: atPoint, size: CGSize(width: 1, height: 1))
        ctx.cgContext.setFillColor(color.cgColor)
        ctx.cgContext.addRect(r)
        ctx.cgContext.drawPath(using: .fill)
    }
    return newImg
}

You can call it like this:

    guard let image = UIImage(named: "pixelTest") else { return }

    let modifiedImage = setColor(color: .red, onImage: image, atPoint: CGPoint(x: 5, y: 5))
DonMag
  • 69,424
  • 5
  • 50
  • 86