2011-12-14 1 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

관련 문제