0

This is a continuation of this thread. My first question was answered and so I thought it would be rude to keep commenting and extending the question.

Using the below code, I am converting an RGBA image into an array of integers. However, when I convert back into an image, the data is weird. My back-conversion process is not the issue, because when I debug the pixel array upon creation, the pixels do not match the original image: They match the distorted one.

I'm wondering what might be the source of these issues.

Original stock image

After conversion and back conversion

The code:

   init?(fromImage image: UIImage!) {
    let imageRef = image!.CGImage
    self.width = CGImageGetWidth(imageRef)
    self.height = CGImageGetHeight(imageRef)
    let colorspace = CGColorSpaceCreateDeviceRGB()
    let bytesPerRow = (4 * width);
    let bitsPerComponent :UInt = 8
    let pixels = UnsafeMutablePointer<UInt8>(malloc(width*height*4))


    var context = CGBitmapContextCreate(pixels, width, height, Int(bitsPerComponent), bytesPerRow, colorspace, CGImageAlphaInfo.PremultipliedLast.rawValue);

    CGContextDrawImage(context, CGRectMake(0, 0, CGFloat(width), CGFloat(height)), imageRef)

    for row in 0 ..< height {
        for col in 0 ..< width {
            let offset = 4 * (width * row) + col
            print("\(pixels[offset]) ", terminator:"")
            print("\(pixels[offset + 1]) ", terminator:"")
            print("\(pixels[offset + 2]) ", terminator:"")
            print("\(pixels[offset + 3]) ", terminator:"")
            print(" | ", terminator:"")
        }
        print(" ")
    }
}

Anything helps! Thanks again.

Community
  • 1
  • 1
Ted Lasso
  • 131
  • 2
  • 10

1 Answers1

2

Your offset logic is slightly flawed

let offset = 4 * (width * row) + col

When row and col are 0, this gives an offset of 0 - that's okay.

When row is 0 and col is 1, this gives an offset of 1 - that's not okay, we just collided with the previous pixel.

The fix is simply to add brackets:

let offset = 4 * ((width * row) + col)

Now a row of 0 and a col of 1 gives 4 - which is correct.


Although, unless you specifically need to work with the pixel position - I usually just prefer to loop over the pixel data in one loop. For example:

for i in 0 ..< width*height {
    let offset = 4 * i
    print("\(pixels[offset]) ", terminator:"")
    print("\(pixels[offset + 1]) ", terminator:"")
    print("\(pixels[offset + 2]) ", terminator:"")
    print("\(pixels[offset + 3]) ", terminator:"")
    print(" | ", terminator:"")
    print(" ")
}
Hamish
  • 78,605
  • 19
  • 187
  • 280
  • Wow. Great work. Fantastic. I feel rather embarrassed I wasted an entire question on this. Should I delete it since the problem is so specific to me? – Ted Lasso Apr 05 '16 at 16:33
  • Hmm... I'm honestly not sure. It's certainly in a grey area near "simple typographical error" - although an argument could be made that as this kind of problem is difficult to catch (no errors are thrown up by the compiler and no runtime exceptions occur) that it may well be useful for a future reader. I'm probably a little biased towards keeping it up, as I answered it. I would suggest keeping it up for at least a few days, see if anyone else from the community finds it close-worthy, and go from there. Although, if you really want to delete it - I have no problem with deleting my answer. – Hamish Apr 05 '16 at 16:49