保存到设备库时UIImage RGB值更改

时间:2013-05-10 14:33:44

标签: ios objective-c uiimage cgimage pixel-manipulation

我正在开发一个需要图像像素处理的项目。我现在正在做的是使用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])];

2 个答案:

答案 0 :(得分: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代码吗?它可能无法保存正确的图像,也可能会被重置。除此之外我无法找到错误

答案 1 :(得分:1)

使用imagePickerController将imagedata压缩成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上搜索时,您可以找到更多这样的帖子。那些只是我参与的那些。