2012-06-08 3 views
1

Очень простой вопрос ... У меня есть массив пикселей, как мне отображать их на экране?Как я могу отобразить массив пикселей в NSWindow?

#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; 
    } 
} 

Вот и все ... теперь, как я могу показать их на экране?

+2

http://www.whathaveyoutried.com? – Luke

+0

Я пробовал использовать CGImage, но я не могу заставить его работать. Чтобы создать CGImage, я должен передать CGDataProvider в качестве параметра, и я не знаю, как это работает ... Кажется, это очень простая задача, поэтому я подумал, что я ошибся ... – GabrielOshiro

ответ

4
  1. Создать новый «Cocoa Application» (если вы не знаете, как создать приложение, какао перейти к Cocoa Dev Center)
  2. Подкласс NSView (если вы не знаете, как подклассы вид read section "Create the NSView Subclass")
  3. Установите NSWindow размера 400x400 на интерфейсе строителя
  4. Используйте этот код в ваш 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 
    
+0

отличный ответ. Я получаю предупреждение о 'kCGImageAlphaNoneSkipFirst' о неправильном типе перечисления, хотя все работает. Также не должны быть освобождены фактические пиксели? В конце концов, где больше всего памяти. – vidstige

0

Существует множество способов сделать это. Одним из наиболее простых является использование CGContextDrawImage. В 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 имеет кучу аргументов, которые я оставил здесь, как правильные значения будут зависеть от того, что ваш формат растрового изображения. See the CGImage reference for details.

Обратите внимание, что если ваше растровое изображение является статическим, возможно, имеет смысл удерживать его до CGImageRef, вместо того, чтобы немедленно утилизировать его. Вы лучше знаете, как работает ваше приложение, поэтому вы решаете, имеет ли это смысл.

+0

Nope .. Тем не менее это не сработает ... Давайте начнем с самого начала ... У меня новый проект с NSWindow, внутри я добавил класс, который расширяет NSView (myView.m). Я должен добавить ваш код внутри drawRect в myView.m. Это оно? – GabrielOshiro

+0

Отправьте свой код в свой вопрос. – duskwuff

0

Я решил эту проблему, используя NSImageView с NSBitmapImageRep для создания изображения из значений пикселей. Существует множество вариантов создания значений пикселей. В моем случае я использовал 32-битные пиксели (RGBA). В этом коде pixels - это гигантский массив значений пикселей. display - это выход для 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); 
+0

Спасибо за ваш ответ, но как я могу сделать выход из NSImageView? – GabrielOshiro

Смежные вопросы