我正在尝试使用找到的here [stackoverflow.com]代码将RBGA像素阵列写入文件,但它失败了。
我将像素信息存储在32位整数的一维数组中,因此该方法的第一位(希望)从32位整数中取出相关位,将它们存储到一个字符数组中。
运行时,a)下面的方法打印出我们没有创建图像(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中找不到等价物。
答案 0 :(得分: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);
};