views:

196

answers:

2

I asked this question earlier and am now trying to explore the idea of making an offscreen image.

Something is going wrong - I think maybe with colour space? I've boiled the code down and down and down, until I eventually can demonstrate the problem with just a few lines.

I have a view with an imageview (called iv) and a button, which when pushed, calls "push"


- (UIImage *) block:(CGSize)size {
    UIGraphicsBeginImageContext(size);
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetFillColor(context, CGColorGetComponents([UIColor redColor].CGColor));
    CGContextFillRect (context, CGRectMake(0, 0, size.width, size.height));
    UIImage *result =  UIGraphicsGetImageFromCurrentImageContext(); 
    UIGraphicsEndImageContext();
    return result;  
}


- (IBAction) push {
    self.iv.image = [self block:CGSizeMake(50.0,50.0)];
}

The issue here is that instead of drawing a 50x50 block in the specified colour, it draws it in a shade of grey, which leads me to think its a colour space error.

I tried the same thing with a Bitmap Context using


- (CGContextRef) createBitmapContextOfSize:(CGSize) size {
    CGContextRef    context = NULL;
    CGColorSpaceRef colorSpace;
    void *          bitmapData;
    int             bitmapByteCount;
    int             bitmapBytesPerRow;

    bitmapBytesPerRow   = (size.width * 4);
    bitmapByteCount     = (bitmapBytesPerRow * size.height);

    colorSpace = CGColorSpaceCreateDeviceRGB();
    bitmapData = malloc( bitmapByteCount );
    if (bitmapData == NULL) {
        fprintf (stderr, "Memory not allocated!");
        return NULL;
    }
    context = CGBitmapContextCreate (bitmapData,
                                     size.width,
                                     size.height,
                                     8,      // bits per component
                                     bitmapBytesPerRow,
                                     colorSpace,
                                     kCGImageAlphaPremultipliedLast);
    //CGContextSetAllowsAntialiasing (context,NO);
    if (context== NULL) {
        free (bitmapData);
        fprintf (stderr, "Context not created!");
        return NULL;
    }
    CGColorSpaceRelease( colorSpace );
    return context;
}

- (UIImage *) block:(CGSize)size {  
    UIGraphicsBeginImageContext(size);
    CGContextRef context = [self createBitmapContextOfSize:size];
    CGContextSetFillColor(context, CGColorGetComponents([UIColor blueColor].CGColor));
    CGContextFillRect (context, CGRectMake(0, 0, size.width, size.height));
    UIImage *result = [UIImage imageWithCGImage: CGBitmapContextCreateImage (context)];
    CGContextRelease(context);
    UIGraphicsEndImageContext();
    return result;
}

with identical results. Grey boxes not (in this case) a blue box.

I'm sure if I can get this to work everything else will follow.

A: 

Found the answer

CGContextSetFillColor(context, CGColorGetComponents([UIColor redColor].CGColor));

fails in the above scenario (but works when used in drawRect!)

CGContextSetRGBFillColor(context, 1, 0, 0, 1);

works correctly.

I think this shows a whole area of ignorance for me. If someone could explain or point me at the correct documentation I would be very grateful.

Andiih
A: 

If you have a CGColor object, just use the CGContextSetFillColorWithColor function.

Peter Hosey
The issue was that i was using [UIColor whatever].CGColor to make my CGColor. For reasons I can't explain this was not working where the CGContextSetRGBFillColor did work. there fore I suspect (but I've not yet tried it) that CGContextSetFillColorWithColor would fail in the same way.
Andiih
I disagree. I believe it's a mismatch between what CGContextSetFillColor expected and what CGColorGetComponents returned. For example, if the context's initial color space is a white color space (which would match PostScript's behavior), then CGContextSetFillColor will read only one or two (white and alpha) components, not knowing that you gave it two more. Using `CGContextSetFillColorWithColor` will also set the color space, preventing the mismatch.
Peter Hosey
That would certainly fit my observations. I'll test it and feed back.
Andiih