2016-05-08 40 views
8

Sto sviluppando un'app per iPad che presenta le foto di un fotografo. Quelle foto sono state caricate su un server web, e serviti direttamente tramite l'applicazione, in cui vengono scaricati e visualizzati utilizzando il seguente metodo:L'immagine caricata dal mio server ha colori errati nell'app per iPad

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

posso osservare un serio cambiamento nella visualizzazione dei colori di ogni foto tra l'originale immagine (che è la stessa quando viene visualizzata dal disco o dal web sul mio Mac e sul Mac del fotografo) e sull'iPad (il risultato è sbagliato nell'app e persino in Safari).

Dopo alcune ricerche ho trovato alcuni post che spiegano come iDevices non usano il profilo di colore incorporato, quindi ho scoperto che stavo andando in questo modo. Le foto vengono salvate utilizzando le seguenti informazioni:

colorspace: RGB, colorprofile: sRGB iec...

ho scoperto che su alcuni oggetti (per esempio this link from imageoptim o analogsenses) che avrei dovuto salvare l'immagine per l'esportazione dispositivo tramite la conversione in sRGB, senza inserire il colore profilo, ma non posso scoprire come potrei farlo? Ogni volta che ho provato (non ho photoshop, quindi ho usato la riga di comando ImageMagick), l'immagine risultante ha le seguenti informazioni, e non è ancora visualizzata correttamente sul mio iPad (e su qualsiasi altro iPad che ho testato):

colorspace: RGB

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

vorrei trasformarlo per visualizzare in modo corretto, qualsiasi idea sarebbe davvero accolto :)

[EDIT] sono riuscito ad ottenere un'immagine corretta utilizzando "salva per web "di Photoshop utilizzando i seguenti parametri: ok photoshop export parameters Ma non sono ancora in grado di applicare automaticamente queste impostazioni a tutte le mie immagini.

+0

colore non modificato, solo l'aspetto cambia a causa della visualizzazione retina del dispositivo. – aBilal17

risposta

1

Per leggere un'immagine, basta usare:

UIImage *image = [UIImage imageWithContentsOfFile:path]; 

quanto riguarda la questione profilo di colore, provare lo strumento sips riga di comando per risolvere i file di immagine. Qualcosa di simile:

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

grazie per l'indicazione sullo strumento sorsi – PhilippeAuriach

0

È possibile ottenere prima lo spazio colore tramite CGImage.

@property(nonatomic, readonly) CGImageRef CGImage 

CGColorSpaceRef CGImageGetColorSpace (
    CGImageRef image 
); 

E lo sbiadimento di colorSpace applica una conversione di formato. Quindi, per ottenere lo spazio colore di un'immagine, faresti:

CGColorSpaceRef colorspace = CGImageGetColorSpace([myUIImage CGImage]); 

Nota: assicurarsi di seguire le regole/Crea/Copia Get per gli oggetti CG.

conversione del colore alla RGB8 (può anche essere applicato a RGB16 o RGB32, cambiando i bit per componente nel metodo 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.h

#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 penso che si potrebbe avere un problema con [UIImage imageWithCGImage:cgImage], Il mio suggerimento è usare [UIImage imageWithContentsOfFile:path] anziché sopra.

Il seguente codice potrebbe essere di aiuto.

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

ho provato e non ha cambiato nulla, l'immagine ha ancora gli stessi colori – PhilippeAuriach