简体   繁体   中英

How can I display an array of pixels on a NSWindow?

Very simple question... I have an array of pixels, how do I display them on the screen?

#define WIDTH 10
#define HEIGHT 10
#define SIZE WIDTH*HEIGHT

unsigned short pixels[SIZE];

for (int i = 0; i < WIDTH; i++) {
    for (int j = 0; j < HEIGHT; j++) {
        pixels[j*HEIGHT + i] = 0xFFFF;
    }
}

That's it... now how can I show them on the screen?

  1. Create a new "Cocoa Application" (if you don't know how to create a cocoa application go to Cocoa Dev Center )
  2. Subclass NSView (if you don't know how to subclass a view read section "Create the NSView Subclass" )
  3. Set your NSWindow to size 400x400 on interface builder
  4. Use this code in your NSView

     #import "MyView.h" @implementation MyView #define WIDTH 400 #define HEIGHT 400 #define SIZE (WIDTH*HEIGHT) #define BYTES_PER_PIXEL 2 #define BITS_PER_COMPONENT 5 #define BITS_PER_PIXEL 16 - (id)initWithFrame:(NSRect)frame { self = [super initWithFrame:frame]; if (self) { // Initialization code here. } return self; } - (void)drawRect:(NSRect)dirtyRect { // Get current context CGContextRef context = (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort]; // Colorspace RGB CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); // Pixel Matrix allocation unsigned short *pixels = calloc(SIZE, sizeof(unsigned short)); // Random pixels will give you a non-organized RAINBOW for (int i = 0; i < WIDTH; i++) { for (int j = 0; j < HEIGHT; j++) { pixels[i+ j*HEIGHT] = arc4random() % USHRT_MAX; } } // Provider CGDataProviderRef provider = CGDataProviderCreateWithData(nil, pixels, SIZE, nil); // CGImage CGImageRef image = CGImageCreate(WIDTH, HEIGHT, BITS_PER_COMPONENT, BITS_PER_PIXEL, BYTES_PER_PIXEL*WIDTH, colorSpace, kCGImageAlphaNoneSkipFirst, // xRRRRRGGGGGBBBBB - 16-bits, first bit is ignored! provider, nil, //No decode NO, //No interpolation kCGRenderingIntentDefault); // Default rendering // Draw CGContextDrawImage(context, self.bounds, image); // Once everything is written on screen we can release everything CGImageRelease(image); CGColorSpaceRelease(colorSpace); CGDataProviderRelease(provider); } @end 

There's a bunch of ways to do this. One of the more straightforward is to use CGContextDrawImage . In drawRect:

CGContextRef ctx = [[NSGraphicsContext currentContext] graphicsPort];
CGDataProviderRef provider = CGDataProviderCreateWithData(nil, bitmap, bitmap_bytes, nil);
CGImageRef img = CGImageCreate(..., provider, ...);
CGDataProviderRelease(provider);    
CGContextDrawImage(ctx, dstRect, img);
CGImageRelease(img);

CGImageCreate has a bunch of arguments which I've left out here, as the correct values will depend on what your bitmap format is. See the CGImage reference for details.

Note that, if your bitmap is static, it may make sense to hold on to the CGImageRef instead of disposing of it immediately. You know best how your application works, so you decide whether that makes sense.

I solved this problem by using an NSImageView with NSBitmapImageRep to create the image from the pixel values. There are lots of options how you create the pixel values. In my case, I used 32-bit pixels (RGBA). In this code, pixels is the giant array of pixel value. display is the outlet for the NSImageView.

    NSBitmapImageRep *myBitmap;
    NSImage *myImage;
    unsigned char *buff[4];
    unsigned char *pixels;
    int width, height, rectSize;
    NSRect myBounds;

    myBounds = [display bounds];
    width = myBounds.size.width;
    height = myBounds.size.height;

    rectSize = width * height;


    memset(buff, 0, sizeof(buff));
    pixels = malloc(rectSize * 4);

    (fill in pixels array)

    buff[0] = pixels;

    myBitmap = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:buff
            pixelsWide:width
            pixelsHigh:height 
            bitsPerSample:8
            samplesPerPixel:4 
            hasAlpha:YES
            isPlanar:NO
            colorSpaceName:NSCalibratedRGBColorSpace
            bitmapFormat:0
            bytesPerRow:(4 * width)
            bitsPerPixel:32];

    myImage = [[NSImage alloc] init];
    [myImage addRepresentation:myBitmap];
    [display setImage: myImage];
    [myImage release];
    [myBitmap release];

    free(pixels);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM