2011-12-14 8 views
3

RBGAピクセル配列をファイルに書き込もうとしていますが、コードhere [stackoverflow.com]が見つかりませんでした。CGBitmapContextCreateはnullを返します。 rbgaピクセル配列をファイルに書き込む

ピクセル情報を32ビット整数の1次元配列に格納するので、このメソッドの最初のビット(うまくいけば)は32ビット整数から適切なビットを取り出し、charの配列に格納します。

、我々は画像を作成しなかった)印刷物(CGBitmapContextCreateImage(bitmapContext)がNULLを返した)以下の方法を実行し、cgImageがnullであるため、理にかなっている画像(RayTracerProject[33126] <Error>: CGBitmapContextCreateImage: invalid context 0x0 ImageIO: <ERROR> CGImageDestinationAddImage image parameter is nil)を、解除しようとすると、b)に死にます。

方法:完全性については

-(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]、CGBitmapContextCreateImageA new bitmap context, or NULL if a context could not be createdを返します見つけましたが、ウォンなぜ文脈を作り出すことができなかったのか理解できません。

私は間違っていますか? [Objective-Cのファイルにピクセル配列を書き込む方がはるかにスマートな方法があれば、私はこの特定のやり方に縛られていません。このプロジェクトは、私が数年前に行ったJavaのポートです - 私はFileOutputStreamを使用しましたが、Objective-Cでは同等のものを見つけることができません。

答えて

3

私はそれを今作業しています - 誰かがこの役に立つ日を見つけた場合に備えてこれを投稿してください。私は、例えば、CGBitmapContextCreateへの呼び出し内の行あたりのバイトのためwidth*4を使用していない、と私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

関連する問題