2016-05-08 16 views
8

Tôi đang phát triển một ứng dụng iPad trình bày ảnh từ một nhiếp ảnh gia. Những hình ảnh được đăng tải trên một máy chủ web, và phục vụ trực tiếp thông qua các ứng dụng, nơi họ được tải xuống và hiển thị bằng cách sử dụng phương pháp dưới đây:Ảnh được tải từ máy chủ của tôi có màu sai trên ứng dụng 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; 
} 

tôi có thể quan sát sự thay đổi nghiêm trọng trong màn hình hiển thị màu sắc của hình ảnh giữa bản gốc hình ảnh (đó là giống nhau khi hiển thị từ đĩa hoặc từ web trên máy Mac của tôi và máy Mac của nhiếp ảnh gia) và trên iPad (kết quả là sai trong ứng dụng và ngay cả trong Safari).

Sau một số tìm kiếm, tôi đã tìm thấy một số bài viết giải thích cách iDevices không sử dụng cấu hình màu được nhúng, vì vậy tôi thấy tôi đang đi theo cách này. Các bức ảnh được lưu sử dụng các thông tin sau:

colorspace: RGB, colorprofile: sRGB iec...

tôi phát hiện ra một số điều (ví dụ this link from imageoptim hoặc analogsenses) rằng tôi nên lưu các bức tranh xuất khẩu thiết bị bằng cách chuyển đổi nó để sRGB, mà không cần nhúng màu hồ sơ, nhưng tôi không thể tìm hiểu làm thế nào tôi có thể làm điều đó? Mỗi lần tôi thử (tôi không có photoshop, vì vậy tôi đã sử dụng dòng lệnh ImageMagick), ảnh kết quả có thông tin sau và vẫn không hiển thị chính xác trên iPad của tôi (và bất kỳ iPad nào khác mà tôi đã thử nghiệm):

colorspace: RGB

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

tôi muốn chuyển đổi nó để hiển thị một cách chính xác, bất kỳ ý tưởng sẽ được thực sự hoan nghênh :)

[EDIT] tôi đã thành công để có được một hình ảnh chính xác sử dụng "tiết kiệm cho web "tùy chọn photoshop sử dụng các thông số sau: ok photoshop export parameters Nhưng tôi vẫn không thể tự động áp dụng các cài đặt đó cho tất cả hình ảnh của mình.

+0

màu không thay đổi ,, chỉ xuất hiện thay đổi do màn hình hiển thị võng mạc của thiết bị. – aBilal17

Trả lời

1

Để đọc một hình ảnh, chỉ cần sử dụng:

UIImage *image = [UIImage imageWithContentsOfFile:path]; 

Đối với vấn đề hồ sơ màu, hãy thử các công cụ sips dòng lệnh để sửa chữa các tập tin hình ảnh. Một cái gì đó như:

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

cảm ơn cho các dấu hiệu trên các công cụ sips – PhilippeAuriach

0

Bạn có thể nhận được không gian màu đầu tiên thông qua CGImage.

@property(nonatomic, readonly) CGImageRef CGImage 

CGColorSpaceRef CGImageGetColorSpace (
    CGImageRef image 
); 

Và bỏ màu Không áp dụng chuyển đổi định dạng. Vì vậy, để có được những không gian màu của một hình ảnh, bạn muốn làm:

CGColorSpaceRef colorspace = CGImageGetColorSpace([myUIImage CGImage]); 

Lưu ý: hãy chắc chắn để làm theo các get/tạo/quy tắc bản sao cho các đối tượng CG.

Màu chuyển đổi sang RGB8 (cũng có thể được áp dụng cho RGB16 hoặc RGB32, thay đổi các bit cho mỗi thành phần trong phương pháp 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 Tôi nghĩ rằng bạn có thể có vấn đề với [UIImage imageWithCGImage:cgImage], Đề nghị của tôi là sử dụng [UIImage imageWithContentsOfFile:path] thay vì ở trên.

Mã dưới đây có thể giúp bạn.

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

Tôi đã cố gắng và nó đã không thay đổi bất cứ điều gì, hình ảnh vẫn có cùng một màu sắc – PhilippeAuriach

Các vấn đề liên quan