Drawing an offscreen coloured square returns a greyscale image

你。 提交于 2019-12-11 07:04:49

问题


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.


回答1:


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




回答2:


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.




回答3:


This is happening because CGContextSetFillColor() has no effect unless CGContextSetFillColorSpace() has been called first at some point in the context's lifetime.

Both CGContextSetFillColorWithColor() and CGContextSetRGBFillColor() also set the fill colorspace, which is why those work.

As Peter Hosey says, the best thing to do in your example is CGContextSetFillColorWithColor().



来源:https://stackoverflow.com/questions/2383748/drawing-an-offscreen-coloured-square-returns-a-greyscale-image

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!