1
votes

I'm writing application that operates on black&white images. I'm doing it by passing a NSImage object into my method and then making NSBitmapImageRep from NSImage. All works but quite slow. Here's my code:

- (NSImage *)skeletonization: (NSImage *)image
{
    int x = 0, y = 0;
    NSUInteger pixelVariable = 0;

    NSBitmapImageRep *bitmapImageRep = [[NSBitmapImageRep alloc] initWithData:[image TIFFRepresentation]];

    [myHelpText setIntValue:[bitmapImageRep pixelsWide]];
    [myHelpText2 setIntValue:[bitmapImageRep pixelsHigh]];

    NSColor *black = [NSColor blackColor];
    NSColor *white = [NSColor whiteColor];
    [myColor set];
    [myColor2 set];

    for (x=0; x<=[bitmapImageRep pixelsWide]; x++) {
        for (y=0; y<=[bitmapImageRep pixelsHigh]; y++) {
            // This is only to see if it's working
            [bitmapImageRep setColor:myColor atX:x y:y];
        }
    }

    [myColor release];
    [myColor2 release];

    NSImage *producedImage = [[NSImage alloc] init];
    [producedImage addRepresentation:bitmapImageRep];
    [bitmapImageRep release];

    return [producedImage autorelease];
}

So I tried to use CIImage but I don't know how to get into each pixel by (x,y) coordinates. That is really important.

1
Why are you setting the colors? This is completely pointless, since there is no locked focus and you are also not drawing anything with those colors. Not that removing this will speed-up your code, I just wanted to let you know.Mecki
The way how you are accessing each pixel is rather suboptimal and I'm also not sure what you are exactly trying to do here; all you do is changing the color of each pixel in the image it to some color (no idea where this comes from), but you say that this code is only to see if it's working. I need more information if you want me to post a better solution, e.g. what kind of image is the source image named and what kind of image is the produced image. I think I can certainly speed up your code dramatically, but not if I have no idea what it is supposed to do.Mecki

1 Answers

0
votes

Use the representations array property from NSImage, to get your NSBitmapImageRep. It should be faster than serializing your image to a TIFF and then back.

Use the bitmapData property of the NSBitmapImageRep to access the image bytes directly.

eg

unsigned char black = 0;
unsigned char white = 255;

NSBitmapImageRep* bitmapImageRep = [[image representations] firstObject];
// you will need to do checks here to determine the pixelformat of your bitmap data
unsigned char* imageData = [bitmapImageRep bitmapData];

int rowBytes = [bitmapImageRep bytesPerRow];
int bpp = [bitmapImageRep bitsPerPixel] / 8;

for (x=0; x<[bitmapImageRep pixelsWide]; x++) {  // don't use <= 
    for (y=0; y<[bitmapImageRep pixelsHigh]; y++) {

       *(imageData + y * rowBytes + x * bpp ) = black; // Red
       *(imageData + y * rowBytes + x * bpp +1) = black;  // Green
       *(imageData + y * rowBytes + x * bpp +2) = black;  // Blue
       *(imageData + y * rowBytes + x * bpp +3) = 255;  // Alpha
    }
}

You will need to know what pixel format you are using in your images before you can go playing with its data, look at the bitsPerPixel property of NSBitmapImageRep to help determine if your image is in RGBA format.

You could be working with a gray scale image, or an RGB image, or possibly CMYK. And either convert the image to what you want first. Or handle the data in the loop differently.