2013-02-20 39 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来修改像素数据的红色分量,然后使用修改的像素阵列创建原始图像的有色版本。