Search code examples
objective-ccocoaxcode4pixelcgimage

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?


Solution

    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