14

I have been trying to convert an array RGBA data (int bytes) into a UIImage. My code looks like as follows:

/*height and width are integers denoting the dimensions of the image*/
unsigned char *rawData = malloc(width*height*4);

for (int i=0; i<width*height; ++i) 
{
    rawData[4*i] = <red_val>;
    rawData[4*i+1] = <green_val>;
    rawData[4*i+2] = <blue_val>;
    rawData[4*i+3] = 255;
}


/*I Have the correct values displayed
    - ensuring the rawData is well populated*/

NSLog(@"(%i,%i,%i,%f)",rawData[0],rawData[1],rawData[2],rawData[3]/255.0f);
NSLog(@"(%i,%i,%i,%f)",rawData[4],rawData[5],rawData[6],rawData[7]/255.0f);
NSLog(@"(%i,%i,%i,%f)",rawData[8],rawData[9],rawData[10],rawData[11]/255.0f);



CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, 
                                                          rawData, 
                                                          width*height*4, 
                                                          NULL);

int bitsPerComponent = 8;
int bitsPerPixel = 32;
int bytesPerRow = 4*width;
CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB();
CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault;
CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault;
CGImageRef imageRef = CGImageCreate(width,
                                    height,
                                    8,
                                    32,
                                    4*width,colorSpaceRef,
                                    bitmapInfo,
                                    provider,NULL,NO,renderingIntent);
/*I get the current dimensions displayed here */
NSLog(@"width=%i, height: %i", CGImageGetWidth(imageRef),
      CGImageGetHeight(imageRef) );
UIImage *newImage = [UIImage imageWithCGImage:imageRef];
/*This is where the problem lies. 
  The width, height displayed are of completely different dimensions
  viz. the width is always zero and the height is a very huge number */

NSLog(@"resultImg width:%i, height:%i",
          newImage.size.width,newImage.size.height);


return newImage;

The output image that I receive is an image of width 0, and height 1080950784 (assuming my initil height and width were 240 and 240). I have been trying to get this sorted out and have checked many related forums e.g. (link text) on how to go about it but with little success.

chochim
  • 1,710
  • 5
  • 17
  • 30
  • 1
    Note that `kCGBitmapByteOrderDefault` does not seem to transfer the alpha channel to the image. Use `kCGBitmapByteOrder32Big|kCGImageAlphaLast` instead. – Brian White Mar 19 '14 at 15:31
  • I think you should relase colorSpaceRef (`CGColorSpaceRelease(colorSpaceRef)`) before returning newImage. – velkyel Jan 13 '15 at 08:16
  • @velkyel he also has to release data provider `CGDataProviderRelease(provider);` – medvedNick Mar 26 '15 at 09:47
  • Any CG function with "create" in it should be released. So, besides `colorSpaceRef` and `provider` mentioned by velkyel and medvedNick, you also need to release `CGImageRef` by calling `CGImageRelease(imageRef);`. – Zhigang An May 24 '17 at 03:13
  • You may want to consider `NSMutableData* mutData = [[NSMutableData alloc] initWithCapacity:height * width * 4]; unsigned char *rawData =mutData.mutableBytes;` instead of `unsigned char *rawData = malloc(width*height*4);` – enthusiasticgeek Mar 23 '19 at 12:34

3 Answers3

12

It turns out the problem is a pretty silly mistake that both of us overlooked. UIImage dimensions are stored as floats, not integers. :D

Try

NSLog(@"resultImg width:%f, height:%f",
          newImage.size.width,newImage.size.height);

Instead. The image size has been transferred correctly.

Thomson Comer
  • 3,919
  • 3
  • 30
  • 32
2

The problem is solved now. I get the image that I want displayed but still unable to figure out why the width and height are different. Essentially nothing wrong with the program per say. The only problem being width and height.

chochim
  • 1,710
  • 5
  • 17
  • 30
2

I just independently verified this problem, I think it should be reported as a bug to Apple. +(UIImage)imageWithCGImage: doesn't properly transfer the width and height of the source CGImageRef to the UIImage.

mattjgalloway
  • 34,792
  • 12
  • 100
  • 110
Thomson Comer
  • 3,919
  • 3
  • 30
  • 32