2013-05-10 5 views
2

Я работаю над проектом, для которого требуется манипуляция пикселями изображения. Сейчас я использую UIImagePicker для получения UIImage из библиотеки устройств. Затем я конвертирую его в CGImage, получаю значения RBG и немного меняю их.Значения UIImage 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]; 
} 

Edit: Я использую 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])]; 
+0

Извините, но я не вижу, чтобы вы сохраняли изображение в любом месте. при импорте изображения у вас есть копия изображения, а не фактическое изображение, необходимое для сохранения фактического изображения в библиотеке фотографий, чтобы оно не выполнялось автоматически. Если я ошибаюсь и фактически сохраняю фотографию в библиотеке фотографий, напишите код – Radu

+1

, в каком формате вы сохраняете (например, jpg, png)? – bobnoble

+0

Опубликуйте код, который содержит значения RGB, и когда вы редактируете значения RGB – Divyu

ответ

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 вы можете найти больше сообщений, подобных этому. Это те, кого я принимал.

+0

Спасибо! Это дает мне много материала, чтобы порыться и обязательно предоставит некоторые необходимые ответы! – Firo

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]; 

    } 

EDIT: я не сделал см. полный код. Для процесса сохранения моя ошибка извините. Код выглядит нормально, он должен сохранять изображение, вы можете проверить код RGB для изображения перед сохранением его? это может не сохранить правильное изображение или оно может быть сброшено. другое, что я не вижу, чтобы найти ошибку

+0

Теперь у вас будет 2 изображения оригинала и измененного изображения. если вы хотите изменить то же изображение, которое немного сложнее, попробуйте это сейчас и скажите мне, работает ли оно – Radu

+0

Я пробовал использовать ваш код и имею ту же проблему. Данные на самом деле не изменены. Я могу проверить прямо перед тем, как сохранить, что биты изменены и исправлены, но когда я вручную прочитал изображение обратно через UIImagePicker, они не изменились. Если изображение изменено, и я его сохраню, должен ли я использовать 'UIImagePickerControllerOriginalImage', чтобы прочитать его или что-то еще? – Firo

+0

Хорошо, используя ваш код Я сохраняю изображение, и мой селектор вызывается. Я даже могу напечатать двоичный код «образа», данный мне в этом методе, и он правильный, и он добавлен в библиотеку фотографий. Затем я устанавливаю UIImagePicker в ноль и повторно инициализирую новый. Тем не менее, когда я прочитал недавно добавленное изображение и распечатал двоичный файл, он не изменился! – Firo

 Смежные вопросы

  • Нет связанных вопросов^_^