画像のピクセル操作が必要なプロジェクトに取り組んでいます。私が今行っているのは、デバイス ライブラリから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])];