Я пытаюсь записать массив пикселей RBGA в файл, используя найденный код здесь [stackoverflow.com], но это не удается.
Я храню информацию о своих пикселях в одномерном массиве 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;
};
Согласно найденным документам здесь [developer.apple.com], CGBitmapContextCreateImage
вернет A new bitmap context, or NULL if a context could not be created
, но не поможет мне понять, почему не удалось создать контекст.
Что я делаю не так? [Кроме того, если есть намного более умный способ записи массива пикселей в файл в Objective-C, я не привязан к этому конкретному способу работы - этот проект является портом от Java, который я сделал несколько лет назад - Я использовал FileOutputStream, но не могу найти эквивалент в Objective-C].