2011-07-28 10 views
7

OpenGL ES 2.0 dokusu olarak kullanılacak bir RGBA8 resmi oluşturmaya çalışıyorum.Çekirdek Grafikte bir RGBA görüntüsü nasıl oluşturulur?

+(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; 
} 

Ne yazık ki, CGColorSpaceCreateDeviceRGBA var ve şu hatayla CGColorSpaceCreateDeviceRGB sonuçları:

CGBitmapContextCreate: unsupported parameter combination: 8 integer bits/component; 32 bits/pixel; 3-component color space; kCGImageAlphaLast; 448 bytes/row. 

ben OpenGL burada istediği doğru RGBA8 biçimi oluşturmak için ne eksik?

Güncelleme: Ben yanlışlıkla denedim çeşitli varyasyonları biridir kCGImageAlphaLast için (ben kod yapıştırılan kopya zaman olduğu) kCGImageAlphaNone den CGBitmapContextCreate son parametre değiştirdi.

Güncelleme 2: İçerik UIGraphicsBeginImageContext() oluşturulmamış ise UIGraphicsGetImageFromCurrentImageContext() döner nil, nedenle farklı bir görüntü elde etmek için gerekli olan: [UIImage imageWithCGImage:CGBitmapContextCreateImage(contextRef)].

cevap

14

Oluşturma sırasında belirttiğiniz renk alanı böyle bir hataya neden olmaz.

o hata alıyorsanız nedeni bileşen başına 8 bit, sen bytesPerRow için geçirilen 4*size.width değeri, henüz kCGImageAlphaNone bir bitmapInfo parametresinde tahminen 4 renk bileşenlerini belirttiğiniz olmasıdır. kCGImageAlphaNone, RGBA değil, yalnızca RGB anlamına gelir. RGBA'u istiyorsanız, büyük olasılıkla kCGImageAlphaLastkCGImageAlphaPremultipliedLast belirtmeniz gerekir.

[EDIT] Üzgünüz. kCGImageAlphaLast değil kCGImageAlphaPremultipliedLast demeliydim.

Yani, böyle bir şey:

CGColorSpaceRef colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB); 
CGContextRef contextRef = CGBitmapContextCreate(NULL, 
               size.width, 
               size.height, 
               8, 
               4 * size.width, 
               colorSpace, 
               kCGImageAlphaPremultipliedLast); 
+1

Bu cevap çok yerinde, 90 hesaplar. :) –

+1

Bunu da denedim; Ne yazık ki aynı (ish) hatası alıyorum: "CGBitmapContextCreate: desteklenmeyen parametre birleşimi: 8 tamsayı bit/bileşen; 32 bit/piksel; 3 bileşenli renk alanı; kCGImageAlphaLast; 448 bayt/satır." –

+0

Sorunun, hatanın hala kCGImageAlphaLast ile gerçekleştiğini göstermek için güncelledim. –

1

ben kCGImageAlphaPremultipliedLast kullanılarak olsa bile aynı unsupported parameter combination hatayı alıyordum. Benim durumumdaki sorun, elde ettiğim genişliğin kesirli olduğu ortaya çıktı. int(width)'u CGBitmapContextCreate'a geçirerek bir tam sayıya dönüştürmek sorunu çözdü. ikinci bir argüman olarak kesirli genişlikte besleme ile Steven'in comment--

soruna yanıt olarak

--edit bu CGBitmapContextCreate olarak yorumlar değildir, örneğin - belirtildiği gibi, bağımsız değişkenin en örtülü döküm alır işaretsiz tamsayı türü. Bunun yerine, int (width * 4) int (width) * ile aynı olmadığından, bytes_per_row argümanında bir farklılık yaratır * 4. E.g. genişliği 22.5 ise, o zaman genişliği 22 kesiliyorsa, ancak width * 4 değil 88.

+1

İmkansız, "CGBitmapContextCreate" genişlik argümanı zaten bir (işaretsiz) tamsayıdır. Döküm sizin için yapıldı. –

+0

Not bir gözlem bildirdi, bu nedenle, tanım gereği imkansız değil, çünkü. Bunu söyledikten sonra, analizim eksikti. Yanıtımı düzenledim ve kesirli bir genişlik kullanmanın neden bir sorun olduğunu açıklığa kavuşturdum. – er0

+1

Doğru, gözlemleri/ölçümleri sorguluyordum. Netleştirdiğiniz için teşekkürler. Bu arada, OP gibi veri argümanı için NULL kullanıyorsanız, satır başına bayt için 0 da geçirirsiniz, böylece sistem doğru (ve belki de daha da performanslı) bir değer seçebilir. –

0
CGColorSpaceRef colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB); 

    CGBitmapInfo bitmapInfo = kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Little; 

    CGContextRef theContext = CGBitmapContextCreate(NULL, imgSize.width, imgSize.height, 8, 4*imgSize.width, colorSpace, bitmapInfo);