0

Core Graphicsを使用してピクセルごとの画像フィルターを作成しようとしています(CFDataを使用してCGImageを符号なし整数に分割します)

しかし、処理されたデータを使用して画像を作成しようとすると、結果の画像は大幅に異なる色で表示されます。

ループ全体をコメントアウトしました。実際にピクセルのrgb値を変更しても、何も変更されません。

フィルタで使用しているUIImageを初期化するとき。UIGraphicsBeginContext();でdrawInRectを使用してサイズ変更を行います。カメラから撮影した画像。

サイズ変更手順を削除して、カメラから直接画像を設定すると、フィルタは問題なく機能しているようです。これが私が使用している画像を初期化するコードです(didFinishPickingImageの中から)

self.editingImageUIImageViewでself.editingUIImageあり、UIImageです

-(void)imagePickerController:(UIImagePickerController *)picker
  didFinishPickingImage : (UIImage *)image
             editingInfo:(NSDictionary *)editingInfo
{

self.didAskForImage = YES;

UIGraphicsBeginImageContext(self.editingImage.frame.size);

float prop = image.size.width / image.size.height;

float left, top, width, height;

if(prop < 1){

    height = self.editingImage.frame.size.height;

    width = (height / image.size.height) * image.size.width;

    left = (self.editingImage.frame.size.width - width)/2;

    top = 0;

}else{

    width = self.editingImage.frame.size.width;

    height = (width / image.size.width) * image.size.height;

    top = (self.editingImage.frame.size.height - height)/2;

    left = 0;

}

[image drawInRect:CGRectMake(left, top, width, height)];

self.editingUIImage = UIGraphicsGetImageFromCurrentImageContext();

UIGraphicsEndImageContext();



self.editingImage.image = self.editingUIImage;

[self.contrastSlider addTarget:self action:@selector(doImageFilter:) forControlEvents:UIControlEventValueChanged];

[self.brightnessSlider addTarget:self action:@selector(doImageFilter:) forControlEvents:UIControlEventValueChanged];

[picker dismissModalViewControllerAnimated:YES];
picker = nil;
}

位置に応じて、必要な方法で画像のサイズを変更します。

これが画像フィルタリング機能です。関係がないため、実際のループの内容を削除しました。

- (void) doImageFilter:(id)sender{


CGImageRef src = self.editingUIImage.CGImage;

CFDataRef dta;
dta = CGDataProviderCopyData(CGImageGetDataProvider(src));

UInt8 *pixData = (UInt8 *) CFDataGetBytePtr(dta);

int dtaLen = CFDataGetLength(dta);

for (int i = 0; i < dtaLen; i += 3) {
    //the loop
}

CGContextRef ctx;

ctx = CGBitmapContextCreate(pixData, CGImageGetWidth(src), CGImageGetHeight(src), 8, CGImageGetBytesPerRow(src), CGImageGetColorSpace(src), kCGImageAlphaPremultipliedLast);

CGImageRef newCG = CGBitmapContextCreateImage(ctx);
UIImage *new = [UIImage imageWithCGImage:newCG];

CGContextRelease(ctx);
CFRelease(dta);
CGImageRelease(newCG);

self.editingImage.image = new;

}

画像は最初はこんな感じです

http://picsilk.com/media/before.png

そして、doImageFilterを実行した後...

http://picsilk.com/media/before.png

前述のように、これは上記のサイズ変更方法を使用した場合にのみ発生します。

本当にこれに困惑し、一日中それを研究してきました...どんな助けも非常にありがたいです!

乾杯

更新:すべての画像オブジェクトの色空間を調べましたが、それらはすべてkCGColorSpaceDeviceRGBです。この1人にかなり困惑しました。画像を符号なし整数に分割すると、何か問題が発生する可能性がありますが、何がわからないのでしょうか。

4

1 に答える 1

1

あなたの問題は最後の行にあります:

ctx = CGBitmapContextCreate(pixData, 
                            CGImageGetWidth(src), 
                            CGImageGetHeight(src), 
                            8, 
                            CGImageGetBytesPerRow(src), 
                            CGImageGetColorSpace(src), 
                            kCGImageAlphaPremultipliedLast);

ソース画像のデータのアルファとコンポーネントの順序について仮定していますが、これは明らかに正しくありません。を介してソース画像から取得する必要がありますCGImageGetBitmapInfo(src)

このような問題を回避するために、任意のCGImageから始めて、ビットマップのバイトを直接操作する場合は、CGBitmapContext(ソース画像から直接取得するのではなく)自分で指定した形式で作成するのが最適です。 。次に、ソース画像をビットマップコンテキストに描画します。CGは、必要に応じて、画像のデータをビットマップコンテキストの形式に変換します。次に、ビットマップコンテキストからデータを取得し、それを操作します。

于 2012-07-03T02:16:20.527 に答える