2

画像のピクセル操作が必要なプロジェクトに取り組んでいます。私が今行っているのは、デバイス ライブラリからUIImagePickerを受け取るために使用することです。UIImage次に、それを に変換しCGImage、RBG 値を取得して少し変更します。

次に、それを に戻し、UIImageディスクに書き出します。問題は、画像を から読み込むときにUIImagePicker、RBG 値が同じではないことです。値を変更した、画像が実際に書き出される前に、値が正しいことを確認しました。ピクセル値は、読み戻したときにのみ異なり、数個の値だけが異なります。私は興味があります、なぜこれが起こっているのですか、これを回避する方法はありますか? まったく同じ RBG 値を取得したい。

ここに少しのコードがあります。特定のものが必要な場合はお知らせください。

- (void)imagePickerController:(UIImagePickerController *)picker
didFinishPickingMediaWithInfo:(NSDictionary *)info {

    // I only ever manipulate self.editingImage which is directly read from the photo library
    // self.editingImage is a UIImage property
    self.editingImage = [info objectForKey:@"UIImagePickerControllerOriginalImage"];
    self.imageView.image = self.editingImage;

    if (self.option == EDITPIXELS) {
        // After this method completes it automatically calls READPIXELS and the values are correct
        // converts self.editingImage to a CGImage before editing pixels
        [self editImage:self.editingImage];
    } else if (self.option == READPIXELS) {
        // converts self.editingImage to a CGImage before reading pixels, then logs RBG values
        [self readImage:self.editingImage];
    }

    [self.imagePickerPopoverController dismissPopoverAnimated:YES];
}

編集:ここのカテゴリを使用して、画像、カテゴリのコードを保存しています:

-(void)saveImage:(UIImage*)image toAlbum:(NSString*)albumName withCompletionBlock:(SaveImageCompletion)completionBlock {

    //write the image data to the assets library (camera roll)
    [self writeImageToSavedPhotosAlbum:image.CGImage orientation:(ALAssetOrientation)image.imageOrientation 
                       completionBlock:^(NSURL* assetURL, NSError* error) {

                      //error handling
                      if (error!=nil) {
                          completionBlock(error);
                          return;
                      }
                      //add the asset to the custom photo album
                      [self addAssetURL: assetURL 
                                toAlbum:albumName 
                    withCompletionBlock:completionBlock];
                  }];
}

アクションボタンで呼び出しています:

- (IBAction)saveImage:(id)sender {
    // Called before saving to verify the RBG values, they are correct
    [self readImage:self.editingImage];

    // saving image
    [self.library saveImage:self.editingImage toAlbum:@"My Album" withCompletionBlock:^(NSError *error){}];
}

これは、RBG 値を編集するために使用しているコードです。

+ (UIImage *) fromImage:(UIImage *)source toRedColors:(NSArray *)redColorArray {

    // Code adapted from: http://brandontreb.com/image-manipulation-retrieving-and-updating-pixel-values-for-a-uiimage/
    CGContextRef ctx;
    CGImageRef imageRef = [source CGImage];
    NSUInteger width = CGImageGetWidth(imageRef);
    NSUInteger height = CGImageGetHeight(imageRef);
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    byte *rawData = malloc(height * width * 4);
    NSUInteger bytesPerPixel = 4;
    NSUInteger bytesPerRow = bytesPerPixel * width;
    NSUInteger bitsPerComponent = 8;
    CGContextRef context = CGBitmapContextCreate(rawData, width, height, 
                                     bitsPerComponent, bytesPerRow, colorSpace, 
                                     kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
    CGContextDrawImage(context, CGRectMake(0, 0, width, height), imageRef);
    CGContextRelease(context);

    int byteIndex = 0;

    for (NSNumber *n in redColorArray) {
        rawData[byteIndex] = Clamp255([n integerValue]);
        byteIndex += 4;
    }
    ctx = CGBitmapContextCreate(rawData,
                            CGImageGetWidth( imageRef ),
                            CGImageGetHeight( imageRef ),
                            8,
                            bytesPerRow,
                            colorSpace,
                            kCGImageAlphaPremultipliedLast );
    CGColorSpaceRelease(colorSpace);
    imageRef = CGBitmapContextCreateImage (ctx);
    UIImage* rawImage = [UIImage imageWithCGImage:imageRef];
    CGImageRelease(imageRef);
    CGContextRelease(ctx);
    free(rawData);

    return rawImage;
}

値の読み取りは、値を配列に格納し、RBG 値の配列を返すだけであることを除いて、ほぼ同じコードを使用しています (すべての RBG 値を返すのではなく、一部だけを返します)。したがって、代わりに:

rawData[byteIndex] = Clamp255([n integerValue]);

私が使う:

[myMutableArray addObject:@(rawData[byteIndex])];
4

2 に答える 2

1

アプリで変更するだけの画像をライブラリに保存する必要があります。これを試してください 画像をフォト ライブラリに保存してみてから、次のコード行を追加します。

UIImageWriteToSavedPhotosAlbum(rawImage, self, @selector(image:didFinishSavingWithError:contextInfo:), self);

保存を確認するには、次のメソッドを追加します。

    - (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo{

        NSString *str = @"Saved!!!";

        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Saved." message:str delegate:self cancelButtonTitle:nil otherButtonTitles:@"OK", nil];

        [alert show];

    }

編集:保存プロセスの完全なコードは表示されませんでした。私のミス申し訳ありません。コードは問題ないようです。画像を保存する必要があります。保存する直前に、画像の RGB コードを確認できますか? 正しい画像が保存されていないか、リセットされている可能性があります。それ以外は、私は欠点を見つけるために見ることができません

于 2013-05-13T06:58:56.967 に答える
1

imagePickerController を使用すると、画像データは jpg に圧縮され、それだけでデータが変更されます。

本格的な画像操作を行う場合は、AVFoundation を使用する必要があります。ドキュメントの AVCam プロジェクトには、参考として使用できるサンプル コードが含まれています。iOS の問題は、私の知る限り、データを画像として保存する可能性として jpg と png しか提供されないことです。

私のアプリケーションでは、OpenCV ライブラリを使用して、画像データを電話に BMP として保存します。 この投稿では、私の解決策を見ることができますまた、 「645 PRO」アプリの説明へのリンクも表示されます。それらのプログラマーは同じ問題に直面し、アプリがその問題を回避する方法を一般的に説明しています。

アプリで再び使用するためにデータをしばらく保存する必要がある場合は、画像データをNSDataオブジェクトに保存して、携帯電話に書き込むことができます。

(CMSampleBufferRef から) 圧縮せずにまだ UIImage をキャプチャしますか? その問題についてより多くの洞察を提供します。 OpenCV imread() は iOS で画像データを返しません

stackoverflow で検索すると、そのような投稿が他にも見つかります。それらは私が関わったものです。

于 2013-06-27T08:35:05.687 に答える