2

我正在做一个需要图像像素处理的项目。我现在正在做的是用来从设备库UIImagePicker中接收一个。UIImage然后我将其转换为 a CGImage,获取 RBG 值并稍微更改它们。

然后我将其转换回 aUIImage并将其写入磁盘。问题是当我从 中读回图像时,UIImagePickerRBG 值不一样。我更改它们之后和实际写出图像之前,我已经验证了这些值是正确的。只有当我读回它时,像素值才会有所不同,然后只有几个值。我很好奇,为什么会发生这种情况,有什么办法可以解决这个问题吗?我想取回完全相同的 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对象中并将其写入您的手机。

捕获仍然没有压缩的 UIImage(来自 CMSampleBufferRef)?提供了更多关于这个问题的见解。 OpenCV imread() 在 iOS 上不返回图像数据

当您在 stackoverflow 上搜索时,您可以找到更多类似的帖子。这些只是我参与的那些。

于 2013-06-27T08:35:05.687 回答