NSImage/NSBitmapImageRep color shifts when creating scaled copy

  • I'm trying to create a scaled-down copy of a large NSBitmapImageRep
    (i.e., 3200x2400 -> 320x240). The smaller image eventually gets
    passed to OpenGL for drawing. What I'm finding is that the copy has
    color shifted. When I draw the copy, it appears to be darker and more
    saturated than the original.

    I have tried several ways to get a copy that has the same color
    characteristics as the original but no success so far. My simplest
    version looks like this:

    NSRect resizedBounds = {NSZeroPoint, desiredBitmapSize};
    NSImage* resizedImage = [[[NSImage alloc]
    initWithSize:resizedBounds.size] autorelease];

    [resizedImage lockFocus];
    [[NSGraphicsContext currentContext]
    setImageInterpolation:NSImageInterpolationHigh];
    [image drawInRect:resizedBounds fromRect:NSZeroRect
    operation:NSCompositeCopy fraction:1.0];
    [resizedImage unlockFocus];

    bitmapImage = [NSBitmapImageRep imageRepWithData:[resizedImage
    TIFFRepresentation]];

    Am I missing something or is this just how Quartz works? Is there
    another way to get there? I'm not wedded to NSImage and friends if a
    better solution exists elsewhere. This needs to run on 10.4 or later.

    Thanks,
    steve
  • On Fri, Mar 6, 2009 at 2:21 PM, Steve Christensen <punster...> wrote:
    > I'm trying to create a scaled-down copy of a large NSBitmapImageRep (i.e.,
    > 3200x2400 -> 320x240). The smaller image eventually gets passed to OpenGL
    > for drawing. What I'm finding is that the copy has color shifted. When I
    > draw the copy, it appears to be darker and more saturated than the original.

    Sounds like you're falling victim to this problem:
    http://www.4p8.com/eric.brasseur/gamma.html

    --Kyle Sluder
  • On Mar 6, 2009, at 1:15 PM, Kyle Sluder wrote:

    > On Fri, Mar 6, 2009 at 2:21 PM, Steve Christensen <punster...>
    > wrote:
    >> I'm trying to create a scaled-down copy of a large
    >> NSBitmapImageRep (i.e.,
    >> 3200x2400 -> 320x240). The smaller image eventually gets passed to
    >> OpenGL
    >> for drawing. What I'm finding is that the copy has color shifted.
    >> When I
    >> draw the copy, it appears to be darker and more saturated than the
    >> original.
    >
    > Sounds like you're falling victim to this problem:
    > http://www.4p8.com/eric.brasseur/gamma.html

    In this case what I found out was running into a difference of
    opinion between the ColorSync profile attached to the
    NSBitmapImageRep in the source image and the default one (or lack of
    one) for a newly-created NSBitmapImageRep in the resized image.

    I ended up rewriting my code to create a new NSBitmapImageRep with
    the destination size, then copy what I thought were relevant
    properties (NSImageRGBColorTable, NSImageColorSyncProfileData,
    NSImageGamma) from the source NSBitmapImageRep if they exist. Then
    create a context using +[NSGraphicsContext
    graphicsContextWithBitmapImageRep:] using the destination
    NSBitmapImageRep and draw into that.

    steve
previous month march 2009 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