1

画像の生のピクセルを操作しようとしていますが、いくつかの問題が発生しています。

まず、C4Imageで.CGImageを呼び出すと機能しないため、UIImageを使用してファイルをロードする必要があります。

次に、バイト配列の長さが間違っているようで、画像のサイズや色が正しくないようです。

ここでの議論からいくつかのコードを借りています。

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];

これを行うためのより良い方法はありますか、それとも私はステップを逃していますか?

4

1 に答える 1

1

選ぶ。C4Imageにはメソッドがあり、メインのC4リポジトリ(C4iOS)loadPixelDataをチェックインすると、画像クラスがどのようにピクセルをロードするかを確認できます...これは注意が必要な場合があります。

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で遊ぶことができる要点を作成しました。

Rawピクセルの操作

この要点では、実際にC4ImageオブジェクトからCGImageを取得し、それを使用して生データの配列にデータを入力し、その配列を使用して元の画像のコピーを作成していることがわかります。次に、すべての値を255に変更してピクセルデータの赤のコンポーネントを変更し、変更したピクセル配列を使用して元の画像の色付きバージョンを作成します。

于 2013-02-21T01:00:49.237 に答える