2

My task is to obtain all the image pixels from a UIImage object, and then store them in a variable. It is not difficult for me to do that for colour image:

   CGColorSpaceRef colorSpace = CGImageGetColorSpace(image.CGImage);

    size_t ele = CGColorSpaceGetNumberOfComponents(colorSpace);

    CGFloat cols = image.size.width;
    CGFloat rows = image.size.height;

  // Create memory for the input image
    unsigned char *img_mem;
    img_mem = (unsigned char*) malloc(rows*cols*4);
    unsigned char *my_img;
    my_img = (unsigned char *)malloc(rows*cols*3);


    CGContextRef contextRef = CGBitmapContextCreate(img_mem,                                                                   cols,                       // Width of bitmap
                                                    rows,                       // Height of bitmap
                                                    8,                          // Bits per component
                                                    cols*4,              // Bytes per row
                                                    colorSpace,                 // Colorspace
                                                    kCGImageAlphaNoneSkipLast|kCGBitmapByteOrderDefault); // Bitmap info flags

    CGContextDrawImage(contextRef, CGRectMake(0, 0, cols, rows), image.CGImage);

    CGContextRelease(contextRef);
    CGColorSpaceRelease(colorSpace);

    unsigned int pos_new;
    unsigned int pos_old;
    for(int i=0; i<rows; i++)
    {
        pos_new = i*cols*3;
        pos_old = i*cols*4;

        for(int j=0; j<cols; j++)
        {
            my_img[j*3+pos_new] = img_mem[pos_old+j*4];
            my_img[j*3+pos_new+1] = img_mem[pos_old+j*4+1];
            my_img[j*3+pos_new+2] = img_mem[pos_old+j*4+2];

        }
    }

    free(img_mem);


 //All the pixels are installed in my_img

    free(my_img);

My problem is the above codes are useful for colour image, but for grayscale image I do not how to do it. Any ideas?

feelfree
  • 11,175
  • 20
  • 96
  • 167

2 Answers2

2

The trouble is you've got hard-coded numbers in your code that make assumptions about your input and output image formats. Doing it this way completely depends on the exact format of your greyscale source image, and equally on what format you want the resultant image to be in.

If you are sure the images will always be, say, 8-bit single-channel greyscale, then you could get away with simply removing all occurrences of *4 and *3 in your code, and reducing the final inner loop to only handle a single channel:-

  for(int j=0; j<cols; j++)
  {
    my_img[j+pos_new] = img_mem[pos_old+j];
  }

But if the output image is going to be 24-bit (as your code seems to imply) then you'll have to leave in all the occurrences of *3 and your inner loop would read:-

  for(int j=0; j<cols; j++)
    {
        my_img[j*3+pos_new] = img_mem[pos_old+j];
        my_img[j*3+pos_new+1] = img_mem[pos_old+j];
        my_img[j*3+pos_new+2] = img_mem[pos_old+j];

    }

This would create greyscale values in 24 bits.

To make it truly flexible you should look at the components of your colorSpace and dynamically code your pixel processing loops based on that, or at least throw some kind of exception or error if the image format is not what your code expects.

Echelon
  • 7,306
  • 1
  • 36
  • 34
1

Please refer to the category (UIImage+Pixels) on the link : http://b2cloud.com.au/tutorial/obtaining-pixel-data-from-a-uiimage