我尝试使用图像的原始像素,但我遇到了一些问题。
首先,在C4Image上调用.CGImage不起作用,所以我必须使用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];
有更好的方法可以做到这一点还是我错过了一步?
答案 0 :(得分: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中使用的要点。
在这个要点中,你会看到我实际从C4Image对象中获取CGImage,使用它来填充原始数据数组,然后使用该数组创建原始图像的副本。 然后,我通过将所有值更改为255来修改像素数据的红色分量,然后使用修改后的像素阵列创建原始图像的着色版本。