问题
I'm trying to generate an RGBA8 image from text to use as an OpenGL ES 2.0 texture.
+(UIImage *)imageFromText:(NSString *)text
{
UIFont *font = [UIFont systemFontOfSize:20.0];
CGSize size = [text sizeWithFont:font];
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef contextRef = CGBitmapContextCreate (NULL,
size.width, size.height,
8, 4*size.width,
colorSpace,
kCGImageAlphaLast
);
CGColorSpaceRelease(colorSpace);
UIGraphicsPushContext(contextRef);
[text drawAtPoint:CGPointMake(0.0, 0.0) withFont:font];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsPopContext();
return image;
}
Unfortunately, there's no CGColorSpaceCreateDeviceRGBA
, and CGColorSpaceCreateDeviceRGB
results in the following error:
CGBitmapContextCreate: unsupported parameter combination: 8 integer bits/component; 32 bits/pixel; 3-component color space; kCGImageAlphaLast; 448 bytes/row.
What am I missing to create the proper RGBA8 format that OpenGL wants here?
Update: I changed the last parameter of CGBitmapContextCreate
from kCGImageAlphaNone
(which it was when I copy pasted the code) to kCGImageAlphaLast
, which is one of several variations I've tried in error.
Update 2: UIGraphicsGetImageFromCurrentImageContext()
returns nil if the context was not created with UIGraphicsBeginImageContext()
, so it is necessary to extract the image differently: [UIImage imageWithCGImage:CGBitmapContextCreateImage(contextRef)]
.
回答1:
The color space you specify during creation wouldn't cause an error like that.
The reason you're getting that error is that you've specified 8 bits per component, presumably 4 color components in the 4*size.width
value you passed in for bytesPerRow
, yet a bitmapInfo
parameter of kCGImageAlphaNone
. kCGImageAlphaNone
means only RGB
, not RGBA
. If you want RGBA
, you should most likely specify kCGImageAlphaLast
kCGImageAlphaPremultipliedLast
.
[EDIT] sorry. I should have said kCGImageAlphaPremultipliedLast
, not kCGImageAlphaLast
.
So, something like this:
CGColorSpaceRef colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
CGContextRef contextRef = CGBitmapContextCreate(NULL,
size.width,
size.height,
8,
4 * size.width,
colorSpace,
kCGImageAlphaPremultipliedLast);
回答2:
I was getting the same unsupported parameter combination
error even though I was using kCGImageAlphaPremultipliedLast
. The issue in my case turned out to be that the width I was getting was fractional. Turning it into an integer by passing int(width)
to CGBitmapContextCreate solved the problem.
--Edit in response to Steven's comment--
The issue with feeding in a fractional width as the second argument is not that CGBitmapContextCreate
interprets it as such -- as stated, it gets casted implicitly to the argument's unsigned integer type. Rather, it produces a discrepancy in the bytes_per_row
argument, since int(width * 4) is not the same as int(width) * 4. E.g. if the width is 22.5, then width gets truncated to 22, but width * 4
computes to 90, not 88.
回答3:
CGColorSpaceRef colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
CGBitmapInfo bitmapInfo = kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Little;
CGContextRef theContext = CGBitmapContextCreate(NULL, imgSize.width, imgSize.height, 8, 4*imgSize.width, colorSpace, bitmapInfo);
来源:https://stackoverflow.com/questions/6861891/how-do-you-generate-an-rgba-image-in-core-graphics