2011-12-14 19 views
3

我想寫一個RBGA像素數組到文件使用代碼找到here [stackoverflow.com],但它失敗。CGBitmapContextCreate返回null;寫rbga像素數組到文件

我將我的像素信息存儲在32位整數的一維數組中,所以此方法的第一位(希望)將32位整數的相關位存儲到一個字符數組中。

運行時,下面,我們沒有創建圖像的)打印方法(CGBitmapContextCreateImage(bitmapContext)返回NULL)和b)試圖釋放圖像(RayTracerProject[33126] <Error>: CGBitmapContextCreateImage: invalid context 0x0 ImageIO: <ERROR> CGImageDestinationAddImage image parameter is nil),這是有道理的,因爲cgImage爲空時死亡。

的方法:

-(void) write{ 

char* rgba = (char*)malloc(width*height); 
for(int i=0; i < width*height; ++i) { 
    rgba[4*i] = (char)[Image red:pixels[i]]; 
    rgba[4*i+1] = (char)[Image green:pixels[i]]; 
    rgba[4*i+2] = (char)[Image blue:pixels[i]]; 
    rgba[4*i+3] = (char)[Image alpha:pixels[i]]; 
} 
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 
CGContextRef bitmapContext = CGBitmapContextCreate(
                rgba, 
                width, 
                height, 
                8, // bitsPerComponent 
                width, // bytesPerRow 
                colorSpace, 
                kCGImageAlphaNoneSkipLast); 

CFRelease(colorSpace); 

CGImageRef cgImage = CGBitmapContextCreateImage(bitmapContext); 

if (cgImage == NULL) 
    printf("Couldn't create cgImage correctly"). 

CFURLRef url = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, CFSTR("image.png"), kCFURLPOSIXPathStyle, false); 

CFStringRef type = kUTTypePNG; // or kUTTypeBMP if you like 
CGImageDestinationRef dest = CGImageDestinationCreateWithURL(url, type, 1, 0); 

CGImageDestinationAddImage(dest, cgImage, 0); 

CFRelease(cgImage); 
CFRelease(bitmapContext); 
CGImageDestinationFinalize(dest); 
free(rgba); 
}; 

爲了完整起見,我比特移位方法:

// Extract the 8-bit red component from a 32bit color integer. 
+(int) red:(int) color{ 
return (color >> 16) & 0xff; 
}; 

// Extract the 8-bit green component from a 32bit color integer. 
+(int) green:(int) color{ 
    return (color >> 8) & 0xff; 
}; 

// Extract the 8-bit blue component from a 32bit color integer. 
+(int) blue:(int) color{ 
    return (color & 0xff); 
}; 

// Extract the 8-bit alpha component from a 32bit color integer. 
+(int) alpha:(int) color{ 
    return (color >> 24) & 0xff; 
}; 

按照文檔中發現here [developer.apple.com],CGBitmapContextCreateImage將返回A new bitmap context, or NULL if a context could not be created,但韓元不能幫助我理解爲什麼無法創建背景。

我在做什麼錯? [另外,如果在Objective-C中編寫一個像素數組到文件中有更聰明的方法,那麼我就不會被束縛在這種特殊的處理方式上 - 這個項目是我幾年前從Java處理過的端口 - 我使用了FileOutputStream,但在Objective-C中找不到等價物。

回答

3

我現在就開始工作了 - 發佈這個以防別人發現有用的一天。

有與上面的代碼中的一些錯誤 - 我沒有在呼叫時使用width*4每行的字節CGBitmapContextCreate,例如,我的rgba陣列是4倍小,那麼它應該已經。下面的代碼運行,但我不知道圖像保存在哪裏(我將硬編碼一個路徑,直到我知道了)。

-(void) write{ 

//printf("First pixel is: %d\n", pixels[0]); 
// RGBA array needs to be 4x pixel array - using 4bytes per int. 
char* rgba = (char*)malloc(width*height*4); 
//printf("Size of char array: %d\n", width*height*4); 

for(int i=0; i < width*height; ++i) { 
    rgba[4*i] = (char)[Image red:pixels[i]]; 
    rgba[4*i+1] = (char)[Image green:pixels[i]]; 
    rgba[4*i+2] = (char)[Image blue:pixels[i]]; 
    rgba[4*i+3] = (char)[Image alpha:pixels[i]]; 
} 
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 
CGContextRef bitmapContext = CGBitmapContextCreate(
                rgba, 
                width, 
                height, 
                8, // bitsPerComponent 
                width*4, // bytesPerRow (4x larger then width) 
                colorSpace, 
                kCGImageAlphaNoneSkipLast); 

CFRelease(colorSpace); 

CGImageRef cgImage = CGBitmapContextCreateImage(bitmapContext); 

/*if (cgImage == NULL) 
     printf("Couldn't create cgImage correctly"); 
    else 
     printf("Has been created correctly"); 
*/ 
CFURLRef url = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, CFSTR("image.png"), kCFURLPOSIXPathStyle, false); 

CFStringRef type = kUTTypePNG; // or kUTTypeBMP if you like 
CGImageDestinationRef dest = CGImageDestinationCreateWithURL(url, type, 1, 0); 

CGImageDestinationAddImage(dest, cgImage, 0); 

CFRelease(cgImage); 
CFRelease(bitmapContext); 
CGImageDestinationFinalize(dest); 
free(rgba); 
}; 
+0

不要忘了`free(rgba)`。這可以在`CGBitmapContextCreateImage`之後完成,因爲這是一個複製操作。 – Demitri 2012-12-22 16:58:33