1
votes

I would like to modify the color of NSImage pixels based on some variables without using too much toolkit dependent libraries (eg: CIImage). So that later on I can just focus on the pixels manipulation algorithms and keep them platform independent.

My approach was to subclass NSImage and add an attribute

NSBitmapImageRep *originalImage;

During initiation I do:

-(id) initWithContentsOfFile:(NSString *)fileName
{
    if([super initWithContentsOfFile:fileName]){
        NSRect rect = NSMakeRect(0.0, 0.0, self.size.width, self.size.height);
        [self lockFocus];
        originalImage = [[NSBitmapImageRep alloc] initWithFocusedViewRect:rect];
        [self unlockFocus];
    }
    return self;
}

Now when I try to update the image I do:

-(void) updateWithVariables:...
{
    NSInteger width = [originalImage pixelsWide];
    NSInteger height = [originalImage pixelsHigh];
    NSInteger count = width * height * 4;

    unsigned char *bytes = (unsigned char *)calloc(count, sizeof(unsigned char));

    // bytes manipulation

    NSBitmapImageRep* newImg = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:&bytes
                                                                       pixelsWide:width
                                                                       pixelsHigh:height
                                                                    bitsPerSample:[originalImage bitsPerSample]
                                                                  samplesPerPixel:[originalImage samplesPerPixel]
                                                                         hasAlpha:TRUE
                                                                         isPlanar:[originalImage isPlanar]
                                                                   colorSpaceName:[originalImage colorSpaceName]
                                                                     bitmapFormat:[originalImage bitmapFormat]
                                                                      bytesPerRow:[originalImage bytesPerRow]
                                                                     bitsPerPixel:[originalImage bitsPerPixel]];
    while([[self representations] count] > 0){
        NSBitmapImageRep *rep = [[self representations] objectAtIndex: 0];
        [self removeRepresentation:rep];
    }

    [self addRepresentation:newImg];
    [newImg release];
}

But the image doesn't change. I am not sure if I have to use representation or change the containing NSImageView to a context to draw the new image in.

Thanks!

1

1 Answers

0
votes

On this page Apple says:

Treat NSImage and its image representations as immutable objects. The goal of NSImage is to provide an efficient way to display images on the target canvas. Avoid manipulating the data of an image representation directly, especially if there are alternatives to manipulating the data, such as compositing the image and some other content into a new image object.

So you should probably be creating a new image when you want the pixels to change.