我正在做一个需要图像像素处理的项目。我现在正在做的是用来从设备库UIImagePicker
中接收一个。UIImage
然后我将其转换为 a CGImage
,获取 RBG 值并稍微更改它们。
然后我将其转换回 aUIImage
并将其写入磁盘。问题是当我从 中读回图像时,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])];