2013-02-20 73 views
1

我嘗試用圖像的原始像素的工作,我遇到了一些問題。C4Image原始像素

首先,呼籲.CGImage在C4Image不工作,所以我必須使用一個UIImage加載的文件。

二,字節數組似乎是錯誤的長度和圖像似乎並不具備正確的尺寸或顏色。

我從討論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)。代碼爲主線,以填充rawDataCGContextDrawImage通話基本上覆制從圖像的像素成你要玩的數據陣列。

我創建了一個要點,你可以下載C4玩弄。

Working with Raw Pixels

在這個要點,你會看到,我實際上是從一個C4Image對象搶CGImage,用它來填充原始數據的數組,然後使用該數組來創建原始圖像的副本。 然後,我通過將所有值更改爲255來修改像素數據的紅色分量,然後使用修改的像素陣列創建原始圖像的有色版本。