5
votes

I am trying to create a new Image from raw data in unsigned char *. I have the bits per pixel from the data stored. I tried converting raw data into NSData, But result image was nil,

unsigned char *bitmap = myData;

NSUInteger myImageDataLength = strlen( (const char*)bitmap);

NSData *d = [NSData dataWithBytes:bitmap length:myImageDataLength];

imgView.image = [UIImage imageWithData:d];

Then I tried using context to create an image as follows:

CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();
int width = mWidth;
int height = mHeight;
size_t bpp = mBpp;
size_t bpc = 8;
size_t bpr = (width * 4);
CGContextRef context = CGBitmapContextCreate(bitmap, width, height, 8, bpr, colorspace, kCGImageAlphaNone);
CGImageRef cgImage = nil;
if (context != nil) {
    cgImage = CGBitmapContextCreateImage (context);
    CGContextRelease(context);
}
CGColorSpaceRelease(colorspace);
UIImage *newImage = [UIImage imageWithCGImage:cgImage];

I am getting an error message like <Error>: CGBitmapContextCreate: unsupported parameter combination: 8 integer bits/component; 24 bits/pixel; 3-component color space; kCGImageAlphaNone; 64 bytes/row.

I tried solving it by setting many values but cant find any result. I googled on internet to find this solution but all others are creating an image from existing images so they get the values of bits per components and all that... How can I create image from this data???

Original Image:

enter image description here

Resulting image:

enter image description here

Resulting image should be warped. (Warped same as fatBooth and other application)

2
Which image format do you have the data in? - Chaitanya Gupta
Why are you computing the length of your bitmap data with strlen()? It will stop when it sees a null character. Aren't you storing your png image in a binary format? - Chaitanya Gupta
No... Actually unsigned char * comes after some manipulations. I dont know what is the size, So I calculated like this. Can u suggest any other way??? Data is not coming from any pre created image. I want to create an UIImage from this data. - DivineDesert
Typically, in C, most array operations pass the array length alongwith a pointer to the first element of the array. If you don't have it, maybe you will need to parse the PNG data to compuate the length -- en.wikipedia.org/wiki/… - Chaitanya Gupta
The image is very far from what it's supposed to look. Most likley bytesPerPixel is wrong. Try to change from 3 to 4 or vice versa. But even then: are you sure the raw pixel data contains a valid image? Have you tried to display the original image without the warping? - Codo

2 Answers

6
votes

The following code creates a UIImage instance from raw pixel data assuming you have:

  • pixelData: the raw pixel data
  • imageWidth, imageHeight: the image dimensions
  • scanWidth: the number of bytes per scanline
  • bytesPerPixel: the number of bytes used per pixel, usually 4

The resulting UIImage is assigned to the variable uiImage.

CGDataProviderRef provider = CGDataProviderCreateWithData(
    NULL, 
    pixelData, 
    imageHeight * scanWidth, 
    NULL);

CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB();
CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault;
CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault;

CGImageRef imageRef = CGImageCreate(imageWidth,
    imageHeight,
    8,
    bytesPerPixel * 8,
    scanWidth,
    colorSpaceRef,
    bitmapInfo,
    provider,
    NULL,
    NO,
    renderingIntent);

UIImage *uiImage = [UIImage imageWithCGImage:imageRef];
CGDataProviderRelease(provider);
CGColorSpaceRelease(colorSpaceRef);
CGImageRelease(imageRef);
0
votes

Try This :-

CGRect screenBounds = [[UIScreen mainScreen] bounds];
GLuint *buffer;
//point the buffer to memory location code that here accordingly
int backingWidth = screenBounds.size.width;
int backingHeight =screenBounds.size.height;    
NSInteger myDataLength = backingWidth * backingHeight * 4;


CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, buffer, myDataLength, releaseScreenshotData);
const int bitsPerComponent = 8;
const int bitsPerPixel = 4 * bitsPerComponent;
const int bytesPerRow = 4 * backingWidth;

CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB();
CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault;
CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault;
CGImageRef imageRef = CGImageCreate(backingWidth,backingHeight, bitsPerComponent, bitsPerPixel, bytesPerRow, colorSpaceRef, bitmapInfo, provider, NULL, NO, renderingIntent);
CGColorSpaceRelease(colorSpaceRef);
CGDataProviderRelease(provider);

 UIImage *myImage = [UIImage imageWithCGImage:imageRef];
CGImageRelease(imageRef);
 [uiimageviewobject setImage:myImage];
 [self addSubview:uiimageviewobject];