2016-05-08 3 views
8

Я разрабатываю приложение для iPad, в котором представлены фотографии от фотографа. Эти фотографии загружены на веб-сервере, и подается непосредственно через приложение, где они загружены и отображены с помощью ниже метода:Картинка, загруженная с моего сервера, имеет неправильные цвета на iPad app

if([[NSFileManager defaultManager] fileExistsAtPath:[url path]]){ 
    CGImageSourceRef source = CGImageSourceCreateWithURL((CFURLRef)url, NULL); 
    CGImageRef cgImage = nil; 
    if(source){ 
     cgImage = CGImageSourceCreateImageAtIndex(source, 0, (CFDictionaryRef)dict); 
    } 

    UIImage *retImage = [UIImage imageWithCGImage:cgImage]; 

    if(cgImage){ 
     CGImageRelease(cgImage); 
    } 
    if(source){ 
     CFRelease(source); 
    } 

    return retImage; 
} 

я могу наблюдать серьезные изменения в отображении цветов фотографий между оригиналом (что является одинаковым при отображении с диска или из Интернета на моем Mac и Mac фотографа) и на iPad (результат неправильный в приложении и даже в Safari).

После некоторого поиска я нашел несколько сообщений, объясняющих, как iDevices не используют встроенный цветовой профиль, поэтому я обнаружил, что так шел. Фотографии сохраняются с помощью следующей информации:

colorspace: RGB, colorprofile: sRGB iec...

я обнаружил на некоторых статьях (например this link from imageoptim или analogsenses), что я должен сохранить изображение для экспорта устройства путем преобразования его в SRGB, не внедряя цвет профиль, но я не могу узнать, как я могу это сделать? Каждый раз, когда я пробовал (у меня нет фотошопа, поэтому я использовал командную строку ImageMagick), результирующее изображение имеет следующую информацию и по-прежнему не отображается правильно на моем iPad (и любых других iPad, которые я тестировал):

colorspace: RGB

Here is a example of a picture that do not display correctly on the iPhone or iPad, but does on the web

Я хотел бы превратить его правильно отобразить его, любая идея будет действительно приветствуется :)

[EDIT] мне удалось получить правильное изображение с помощью «сохранить для web ", используя следующие параметры: ok photoshop export parameters Но я все еще не могу применить эти настройки автоматически ко всем своим фотографиям.

+0

цвет не изменился, только изменение внешнего вида из-за сетчатки дисплея устройства. – aBilal17

ответ

1

Для чтения изображения, просто используйте:

UIImage *image = [UIImage imageWithContentsOfFile:path]; 

Что касается цветового профиля вопроса, попробуйте инструмент sips командной строки, чтобы исправить файлы изображений. Что-то вроде:

mkdir converted 
sips -m "/System/Library/ColorSync/Profiles/sRGB Profile.icc" *.JPG --out converted 
+0

спасибо за указание на инструмент sips – PhilippeAuriach

0

Вы можете получить первое цветовое пространство через CGImage.

@property(nonatomic, readonly) CGImageRef CGImage 

CGColorSpaceRef CGImageGetColorSpace (
    CGImageRef image 
); 

И для того, чтобы отменить цветное пространство, используйте преобразование формата. Таким образом, чтобы получить цветовое пространство изображения, вы могли бы сделать:

CGColorSpaceRef colorspace = CGImageGetColorSpace([myUIImage CGImage]); 

Примечание: убедитесь, что следовать получить/создать/правила копирования для объектов CG.

Преобразование цвета в RGB8 (также может быть применен к RGB16 или RGB32, меняя бит на компонент в методе newBitmapRGBA8ContextFromImage):

// Create a bitmap 
unsigned char *bitmap = [ImageHelper convertUIImageToBitmapRGBA8:image]; 

    // Create a UIImage using the bitmap 
UIImage *imageCopy = [ImageHelper convertBitmapRGBA8ToUIImage:bitmap withWidth:width withHeight:height]; 

    // Display the image copy on the GUI 
UIImageView *imageView = [[UIImageView alloc] initWithImage:imageCopy]; 

ImageHelper.ч

#import <Foundation/Foundation.h> 


@interface ImageHelper : NSObject { 

} 

/** Converts a UIImage to RGBA8 bitmap. 
@param image - a UIImage to be converted 
@return a RGBA8 bitmap, or NULL if any memory allocation issues. Cleanup memory with free() when done. 
*/ 
+ (unsigned char *) convertUIImageToBitmapRGBA8:(UIImage *)image; 

/** A helper routine used to convert a RGBA8 to UIImage 
@return a new context that is owned by the caller 
*/ 
+ (CGContextRef) newBitmapRGBA8ContextFromImage:(CGImageRef)image; 


/** Converts a RGBA8 bitmap to a UIImage. 
@param buffer - the RGBA8 unsigned char * bitmap 
@param width - the number of pixels wide 
@param height - the number of pixels tall 
@return a UIImage that is autoreleased or nil if memory allocation issues 
*/ 
+ (UIImage *) convertBitmapRGBA8ToUIImage:(unsigned char *)buffer 
    withWidth:(int)width 
    withHeight:(int)height; 

@end 

ImageHelper.m

#import "ImageHelper.h" 


@implementation ImageHelper 


+ (unsigned char *) convertUIImageToBitmapRGBA8:(UIImage *) image { 

    CGImageRef imageRef = image.CGImage; 

    // Create a bitmap context to draw the uiimage into 
    CGContextRef context = [self newBitmapRGBA8ContextFromImage:imageRef]; 

    if(!context) { 
     return NULL; 
    } 

    size_t width = CGImageGetWidth(imageRef); 
    size_t height = CGImageGetHeight(imageRef); 

    CGRect rect = CGRectMake(0, 0, width, height); 

    // Draw image into the context to get the raw image data 
    CGContextDrawImage(context, rect, imageRef); 

    // Get a pointer to the data  
    unsigned char *bitmapData = (unsigned char *)CGBitmapContextGetData(context); 

    // Copy the data and release the memory (return memory allocated with new) 
    size_t bytesPerRow = CGBitmapContextGetBytesPerRow(context); 
    size_t bufferLength = bytesPerRow * height; 

    unsigned char *newBitmap = NULL; 

    if(bitmapData) { 
     newBitmap = (unsigned char *)malloc(sizeof(unsigned char) * bytesPerRow * height); 

     if(newBitmap) { // Copy the data 
      for(int i = 0; i < bufferLength; ++i) { 
       newBitmap[i] = bitmapData[i]; 
      } 
     } 

     free(bitmapData); 

    } else { 
     NSLog(@"Error getting bitmap pixel data\n"); 
    } 

    CGContextRelease(context); 

    return newBitmap; 
} 

+ (CGContextRef) newBitmapRGBA8ContextFromImage:(CGImageRef) image { 
    CGContextRef context = NULL; 
    CGColorSpaceRef colorSpace; 
    uint32_t *bitmapData; 

    size_t bitsPerPixel = 32; 
    size_t bitsPerComponent = 8; 
    size_t bytesPerPixel = bitsPerPixel/bitsPerComponent; 

    size_t width = CGImageGetWidth(image); 
    size_t height = CGImageGetHeight(image); 

    size_t bytesPerRow = width * bytesPerPixel; 
    size_t bufferLength = bytesPerRow * height; 

    colorSpace = CGColorSpaceCreateDeviceRGB(); 

    if(!colorSpace) { 
     NSLog(@"Error allocating color space RGB\n"); 
     return NULL; 
    } 

    // Allocate memory for image data 
    bitmapData = (uint32_t *)malloc(bufferLength); 

    if(!bitmapData) { 
     NSLog(@"Error allocating memory for bitmap\n"); 
     CGColorSpaceRelease(colorSpace); 
     return NULL; 
    } 

    //Create bitmap context 

    context = CGBitmapContextCreate(bitmapData, 
      width, 
      height, 
      bitsPerComponent, 
      bytesPerRow, 
      colorSpace, 
      kCGImageAlphaPremultipliedLast); // RGBA 
    if(!context) { 
     free(bitmapData); 
     NSLog(@"Bitmap context not created"); 
    } 

    CGColorSpaceRelease(colorSpace); 

    return context; 
} 

+ (UIImage *) convertBitmapRGBA8ToUIImage:(unsigned char *) buffer 
     withWidth:(int) width 
     withHeight:(int) height { 


    size_t bufferLength = width * height * 4; 
    CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, buffer, bufferLength, NULL); 
    size_t bitsPerComponent = 8; 
    size_t bitsPerPixel = 32; 
    size_t bytesPerRow = 4 * width; 

    CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB(); 
    if(colorSpaceRef == NULL) { 
     NSLog(@"Error allocating color space"); 
     CGDataProviderRelease(provider); 
     return nil; 
    } 

    CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault | kCGImageAlphaPremultipliedLast; 
    CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault; 

    CGImageRef iref = CGImageCreate(width, 
       height, 
       bitsPerComponent, 
       bitsPerPixel, 
       bytesPerRow, 
       colorSpaceRef, 
       bitmapInfo, 
       provider, // data provider 
       NULL,  // decode 
       YES,   // should interpolate 
       renderingIntent); 

    uint32_t* pixels = (uint32_t*)malloc(bufferLength); 

    if(pixels == NULL) { 
     NSLog(@"Error: Memory not allocated for bitmap"); 
     CGDataProviderRelease(provider); 
     CGColorSpaceRelease(colorSpaceRef); 
     CGImageRelease(iref);  
     return nil; 
    } 

    CGContextRef context = CGBitmapContextCreate(pixels, 
       width, 
       height, 
       bitsPerComponent, 
       bytesPerRow, 
       colorSpaceRef, 
       bitmapInfo); 

    if(context == NULL) { 
     NSLog(@"Error context not created"); 
     free(pixels); 
    } 

    UIImage *image = nil; 
    if(context) { 

     CGContextDrawImage(context, CGRectMake(0.0f, 0.0f, width, height), iref); 

     CGImageRef imageRef = CGBitmapContextCreateImage(context); 

     // Support both iPad 3.2 and iPhone 4 Retina displays with the correct scale 
     if([UIImage respondsToSelector:@selector(imageWithCGImage:scale:orientation:)]) { 
      float scale = [[UIScreen mainScreen] scale]; 
      image = [UIImage imageWithCGImage:imageRef scale:scale orientation:UIImageOrientationUp]; 
     } else { 
      image = [UIImage imageWithCGImage:imageRef]; 
     } 

     CGImageRelease(imageRef); 
     CGContextRelease(context); 
    } 

    CGColorSpaceRelease(colorSpaceRef); 
    CGImageRelease(iref); 
    CGDataProviderRelease(provider); 

    if(pixels) { 
     free(pixels); 
    } 
    return image; 
} 

@end 
0

@PhilippeAuriach Я думаю, что вы могли бы иметь проблемы с [UIImage imageWithCGImage:cgImage], Мое предложение использовать [UIImage imageWithContentsOfFile:path] вместо выше.

Ниже приведен код, который может вам помочь.

if([[NSFileManager defaultManager] fileExistsAtPath:[url path]]){ 
    //Provide image path here... 
    UIImage *image = [UIImage imageWithContentsOfFile:path]; 

    if(image){ 
     return image; 
    }else{ 
     //Return default image 
     return image; 
    } 
} 
+0

Я пробовал и ничего не менял, изображение все равно имеет одинаковые цвета – PhilippeAuriach

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

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