2016-05-08 30 views
8

Pracuję nad aplikacją na iPada, która prezentuje zdjęcia od fotografa. Te zdjęcia są przesyłane na serwer i podawane bezpośrednio z aplikacji, gdzie są one pobierane i wyświetlane przy użyciu poniższego sposobu:Obraz załadowany z mojego serwera ma niewłaściwe kolory w aplikacji na iPada

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

mogę obserwować poważne zmiany wyświetlania kolorów na zdjęciach między oryginałem zdjęcie (które jest takie samo, gdy wyświetlane jest na dysku lub w Internecie na komputerze Mac i komputerze Mac) oraz na iPadzie (wynik jest nieprawidłowy w aplikacji, a nawet w Safari).

Po pewnym wyszukiwaniu znalazłem kilka postów wyjaśniających, w jaki sposób iDevices nie używają osadzonego profilu kolorów, więc odkryłem, że jechałem w ten sposób. Zdjęcia są zapisywane przy użyciu następującej informacji:

colorspace: RGB, colorprofile: sRGB iec...

znalazłem się na niektórych artykułów (na przykład this link from imageoptim lub analogsenses), które należy zapisać obraz na eksport urządzeń poprzez przekształcenie go do sRGB, bez osadzania koloru profil, ale nie mogę się dowiedzieć, jak mogłem to zrobić? Za każdym razem, gdy próbowałem (nie mam programu Photoshop, więc użyłem wiersza poleceń ImageMagick), wynikowy obraz zawiera następujące informacje i nadal nie jest wyświetlany poprawnie na moim iPadzie (i innych testowanych iPadach):

colorspace: RGB

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

Chciałbym przekształcić go w celu wyświetlenia go poprawnie, każdy pomysł byłby naprawdę zadowoleniem :)

[EDIT] udało mi się uzyskać prawidłowy obraz, używając „zapisz dla web "Opcje programu Photoshop przy użyciu następujących parametrów: ok photoshop export parameters Ale nadal nie mogę automatycznie zastosować tych ustawień do wszystkich moich zdjęć.

+0

kolor nie został zmieniony, tylko zmiana wyglądu spowodowana wyświetlaniem urządzenia siatkówki. – aBilal17

Odpowiedz

1

Aby odczytać obrazu, wystarczy użyć:

UIImage *image = [UIImage imageWithContentsOfFile:path]; 

Co do koloru profilu emisji, wypróbuj narzędzie sips wiersza polecenia, aby naprawić pliki obrazów. Coś takiego:

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

dzięki za wskazanie na narzędziu łykami – PhilippeAuriach

0

Możesz uzyskać najpierw przestrzeń kolorów poprzez CGImage.

@property(nonatomic, readonly) CGImageRef CGImage 

CGColorSpaceRef CGImageGetColorSpace (
    CGImageRef image 
); 

Odbicie ColorSpace stosuje konwersję formatu. Tak, aby uzyskać przestrzeń kolorów obrazu, można zrobić:

CGColorSpaceRef colorspace = CGImageGetColorSpace([myUIImage CGImage]); 

Uwaga: upewnij się, aby postępować zgodnie z GET/Create/zasady kopiowania dla obiektów z GK.

konwersję koloru RGB8 (mogą również być stosowane do rgb16 lub RGB32 zmieniając bity na próbkę w sposobie 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 myślę, że masz problem z [UIImage imageWithCGImage:cgImage], Moja sugestia jest korzystać [UIImage imageWithContentsOfFile:path] zamiast powyżej.

Poniższy kod może być pomocny.

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

Próbowałem i nic nie zmieniałem, obraz nadal ma te same kolory – PhilippeAuriach