Color matching multiple images in one bitmap

  • (This was originally posted to the Colorsync-dev list about three weeks ago without any activity on the list, so I'm hoping that someone here can help)

    I have an app that is essentially creating a single resultant image from an amalgamation of multiple source images.  Each source image is an NSImage that has a single NSBitmapImageRep which carries with it color profile data in its NSImageColorSyncProfileData property.

    The effective algorithm is:

    NSBitmapImageRep* getBitmapOfImages(NSArray* imagesArray, NSSize bitmapSize)
    {
      NSBitmapImageRep* bitmap = [[[NSBitmapImageRep alloc] initWithBitmapDataPlanes: NULL
                                                                               pixelsWide: bitmapSize.width
                                                                               pixelsHigh: bitmapSize.height
                                                                           bitsPerSample: 8
                                                                         samplesPerPixel: 4
                                                                                 hasAlpha: YES
                                                                                 isPlanar: NO
                                                                           colorSpaceName: NSCalibratedRGBColorSpace
                                                                             bytesPerRow: 0
                                                                             bitsPerPixel: 0] autorelease];

      NSGraphicsContext* bitmapGraphicsContext  = [NSGraphicsContext graphicsContextWithBitmapImageRep:bitmap];
      NSGraphicsContext* originalGraphicsContext = [NSGraphicsContext currentContext];
      [NSGraphicsContext setCurrentContext:bitmapGraphicsContext];

      for (NSImage* image in imagesArray)
      {
      NSRect imageRect = /* calculate rect for particular source image */;
      [image drawInRect:imageRect ...];
      }

      [NSGraphicsContext setCurrentContext:originalGraphicsContext];

      return bitmap;
    }

    The issue I am experiencing is that the color of the resultant image generated by my application when printed does not match the color of the source image when printed from another application (which is in this case Aperture).

    What attributes do I need to use when creating the destination bitmap so that the color of each source image is rendered properly for that source image when the destination image is printed?  Or is there a deeper issue that I am not addressing here?
  • On May 20, 2012, at 9:42 AM, Clarence Locke <clarence...> wrote:

    > (This was originally posted to the Colorsync-dev list about three weeks ago without any activity on the list, so I'm hoping that someone here can help)
    >
    > I have an app that is essentially creating a single resultant image from an amalgamation of multiple source images.  Each source image is an NSImage that has a single NSBitmapImageRep which carries with it color profile data in its NSImageColorSyncProfileData property.
    >
    > The effective algorithm is:
    >
    > NSBitmapImageRep* getBitmapOfImages(NSArray* imagesArray, NSSize bitmapSize)
    > {
    > NSBitmapImageRep* bitmap = [[[NSBitmapImageRep alloc] initWithBitmapDataPlanes: NULL
    > pixelsWide: bitmapSize.width
    > pixelsHigh: bitmapSize.height
    > bitsPerSample: 8
    > samplesPerPixel: 4
    > hasAlpha: YES
    > isPlanar: NO
    > colorSpaceName: NSCalibratedRGBColorSpace
    > bytesPerRow: 0
    > bitsPerPixel: 0] autorelease];
    >
    > NSGraphicsContext* bitmapGraphicsContext  = [NSGraphicsContext graphicsContextWithBitmapImageRep:bitmap];
    > NSGraphicsContext* originalGraphicsContext = [NSGraphicsContext currentContext];
    > [NSGraphicsContext setCurrentContext:bitmapGraphicsContext];
    >
    > for (NSImage* image in imagesArray)
    > {
    > NSRect imageRect = /* calculate rect for particular source image */;
    > [image drawInRect:imageRect ...];
    > }
    >
    > [NSGraphicsContext setCurrentContext:originalGraphicsContext];
    >
    > return bitmap;
    > }
    >
    >
    > The issue I am experiencing is that the color of the resultant image generated by my application when printed does not match the color of the source image when printed from another application (which is in this case Aperture).
    >
    > What attributes do I need to use when creating the destination bitmap so that the color of each source image is rendered properly for that source image when the destination image is printed?  Or is there a deeper issue that I am not addressing here?

    Your context has a color space of NSCalibratedRGBColorSpace, and the images' color values are being converted to that color space when drawn into that context. Then those colors are being converted to the output color space upon printing. If any of the colors are out of gamut in the destination color space, Core Graphics maps them to in-gamut values according to the context's rendering intent.

    If all your images are coming from the same color space, you can specify that color space instead of NSCalibratedRGBColorSpace to avoid one color conversion, and get any blending done in the correct color space.

    The point is you have to pick a color space for your bitmap context, and CalibratedRGB is probably the wrong one for photos coming from Aperture.

    A more fundamental question: is it actually necessary for you to use a bitmap graphics context? I believe a PDF context will retain the color space information of the images drawn into it, which means that only one color space conversion will happen at the time the context is sent to the output device. Plus, sending PDF to the printer will likely be much lighter weight than sending a giant honking bitmap, and will be able to take advantage of a RIP if the user has one.

    --Kyle Sluder
  • On May 21, 2012, at 9:36 AM, Kyle Sluder wrote:

    > A more fundamental question: is it actually necessary for you to use a bitmap graphics context? I believe a PDF context will retain the color space information of the images drawn into it, which means that only one color space conversion will happen at the time the context is sent to the output device. Plus, sending PDF to the printer will likely be much lighter weight than sending a giant honking bitmap, and will be able to take advantage of a RIP if the user has one.

    Kyle,

    If the PDF context allows for multiple images each with their own color space, then that's exactly what I need.  I will look into it.  Thanks!

    Clarence
previous month may 2012 next month
MTWTFSS
  1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31      
Go to today