我正在开发一个需要图像像素处理的项目。我现在正在做的是使用 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];
}
编辑: 我正在使用category from here要保存我的图像,请使用类别中的代码:
-(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])];
最佳答案
使用 imagePickerController 将图像数据压缩为 jpg,仅此一项就会更改数据。
当您想要进行一些严肃的图像处理时,您将需要使用 AVFoundation。文档中的 AVCam 项目提供了示例代码,您可以将其用作引用。据我所知,iOS 的问题是它只提供 jpg 和 png 作为将数据保存为图片的可能性。
对于我的应用程序,我使用 OpenCV 库将图像数据保存为手机上的 BMP。 In this post you can see my solution 。此外,您还可以看到 "645 PRO" 描述的链接。应用程序。这些程序员面临着同样的问题,并一般性地描述了他们的应用程序如何解决这个问题。
如果您只需要保存数据一段时间以便再次在应用中使用它,您可以尝试将图像数据保存在 NSData
对象中并将其写入手机上。
Capture still UIImage without compression (from CMSampleBufferRef)?提供了对此问题的更多见解。 OpenCV imread() returns no image data on iOS .
当您在 stackoverflow 上搜索时,您可以找到更多类似的帖子。这些只是我参与的。
关于ios - UIImage RBG 值在保存到设备库时发生变化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16484687/