2013-02-20 3 views
1

이미지의 원시 픽셀로 작업하려고하는데 몇 가지 문제가 있습니다.C4 원시 이미지 픽셀

먼저, C4Image에서 .CGImage를 호출하면 작동하지 않으므로 파일을로드 할 때 UIImage를 사용해야합니다.

둘째, 바이트 배열의 길이가 잘못되어 이미지의 크기 나 색상이 올바르지 않은 것처럼 보입니다.

I 토론 here.

UIImage *image  = [UIImage imageNamed:@"C4Table.png"]; 
CGImageRef imageRef = image.CGImage; 
NSData *data  = (__bridge NSData *)CGDataProviderCopyData(CGImageGetDataProvider(imageRef)); 
unsigned char * pixels  = (unsigned char *)[data bytes]; 

for(int i = 0; i < [data length]; i += 4) { 
    pixels[i] = 0; // red 
    pixels[i+1] = pixels[i+1]; // green 
    pixels[i+2] = pixels[i+2]; // blue 
    pixels[i+3] = pixels[i+3]; // alpha 
} 

size_t imageWidth     = CGImageGetWidth(imageRef); 
size_t imageHeight     = CGImageGetHeight(imageRef); 
NSLog(@"width: %d height: %d datalength: %d" ,imageWidth ,imageHeight, [data length]); 

C4Image *imgimgimg = [[C4Image alloc] initWithRawData:pixels width:imageWidth height:imageHeight]; 
[self.canvas addImage:imgimgimg]; 

에서 몇 가지 코드를 차용하고있어이 작업을 수행하거나 내가 단계를 놓친 거지 더 좋은 방법이 있나요?

답변

1

닫기. C4Image에는 loadPixelData 메서드가 있으며, 주 C4 repo (C4iOS)을 체크인하면 이미지 클래스가 픽셀을로드하는 방법을 볼 수 있습니다. 까다로울 수 있습니다.

C4Image loadPixelData :

-(void)loadPixelData { 
    const char *queueName = [@"pixelDataQueue" UTF8String]; 
    __block dispatch_queue_t pixelDataQueue = dispatch_queue_create(queueName, DISPATCH_QUEUE_CONCURRENT); 

    dispatch_async(pixelDataQueue, ^{ 
     NSUInteger width = CGImageGetWidth(self.CGImage); 
     NSUInteger height = CGImageGetHeight(self.CGImage); 
     CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 

     bytesPerPixel = 4; 
     bytesPerRow = bytesPerPixel * width; 
     free(rawData); 
     rawData = malloc(height * bytesPerRow); 

     NSUInteger bitsPerComponent = 8; 
     CGContextRef context = CGBitmapContextCreate(rawData, width, height, bitsPerComponent, bytesPerRow, colorSpace, kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big); 
     CGColorSpaceRelease(colorSpace); 
     CGContextDrawImage(context, CGRectMake(0, 0, width, height), self.CGImage); 
     CGContextRelease(context); 
     _pixelDataLoaded = YES; 
     [self postNotification:@"pixelDataWasLoaded"]; 
     pixelDataQueue = nil; 
    }); 
} 

귀하의 질문에 대해이 문제를 수정하려면, 나는 다음과 같은 짓을 :

-(void)getRawPixelsAndCreateImages { 
    C4Image *image  = [C4Image imageNamed:@"C4Table.png"]; 

    NSUInteger width = CGImageGetWidth(image.CGImage); 
    NSUInteger height = CGImageGetHeight(image.CGImage); 
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 

    NSUInteger bytesPerPixel = 4; 
    NSUInteger bytesPerRow = bytesPerPixel * width; 
    unsigned char *rawData = malloc(height * bytesPerRow); 

    NSUInteger bitsPerComponent = 8; 
    CGContextRef context = CGBitmapContextCreate(rawData, width, height, bitsPerComponent, bytesPerRow, colorSpace, kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big); 
    CGColorSpaceRelease(colorSpace); 
    CGContextDrawImage(context, CGRectMake(0, 0, width, height), image.CGImage); 
    CGContextRelease(context); 

    C4Image *imgimgimg = [[C4Image alloc] initWithRawData:rawData width:width height:height]; 
    [self.canvas addImage:imgimgimg]; 

    for(int i = 0; i < height * bytesPerRow; i += 4) { 
     rawData[i] = 255; 
    } 

    C4Image *redImgimgimg = [[C4Image alloc] initWithRawData:rawData width:width height:height]; 
    redImgimgimg.origin = CGPointMake(0,320); 
    [self.canvas addImage:redImgimgimg]; 
} 

픽셀 데이터로 작업하는 방법에 대한 자세한 내용은 상당히 혼란 스러울 수 있습니다 당신 때문에 Core Foundation으로 작업하는 방법을 알아야합니다 (C API). 주 코드 행인 rawData을 채우려면 CGContextDrawImage을 호출해야합니다.이 코드는 기본적으로 이미지의 픽셀을 재생하려는 데이터 배열로 복사합니다.

C4로 다운로드하여 다운로드 할 수있는 요지를 만들었습니다. 이 요점에서

Working with Raw Pixels

당신은 내가 실제로하는 C4Image 개체에서의 CGImage를 잡아 원시 데이터의 배열을 채울 것을 사용하고 원본 이미지의 복사본을 생성하기 위해 해당 배열을 사용하는 것을 볼 수 있습니다 . 그런 다음 모든 값을 255로 변경하여 픽셀 데이터의 빨간색 구성 요소를 수정 한 다음 수정 된 픽셀 배열을 사용하여 원본 이미지의 색조 버전을 만듭니다.