2010-12-04 22 views
9

Ojalá encontrara una respuesta para esto. He buscado y buscado y no pude la respuesta correcta. Aquí está mi situación:Mac OS Cocoa: Dibuja un píxel simple en un lienzo

En una aplicación Cocoa de Mac OS, quiero dibujar un píxel (en realidad unos pocos píxeles) en un área dedicada en la ventana de mi aplicación. Pensé, sería mejor tener un NSImageView colocado allí (lo hice con IB y conecté el tomacorriente a mi delegado de la aplicación) y dibujaré eso en lugar de mi NSWindow.

¿Cómo puedo hacer eso? Mac OS parece ofrecer NSBezierPath como la herramienta de dibujo más básica — ¿es cierto? Esto es completamente impactante para mí. Vengo de una larga historia de programación de Windows y dibujar un píxel en un lienzo es lo más simple, por lo general.

No quiero usar OpenGL y no estoy seguro en qué medida Quartz está involucrado en esto.

Todo lo que quiero es un poco de ayuda sobre cómo puedo llevar a cabo este pseudocódigo en bienes de Objective-C/Cocoa:

imageObj.drawPixel(10,10,blackColor); 

Me encanta escuchar sus respuestas en esto y estoy seguro de que esto ayudará a una Mucha gente comenzando con Cocoa.

Gracias!

Respuesta

-12

NSBezierPath es la única herramienta disponible en Cocoa para dibujar las formas más primitivas y para muchas formas complejas. descripción detallada se puede encontrar aquí: http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CocoaDrawingGuide/Paths/Paths.html%23//apple_ref/doc/uid/TP40003290-CH206-BBCHFJJG http://en.wikibooks.org/wiki/Programming_Mac_OS_X_with_Cocoa_for_Beginners/Graphics_-_Drawing_with_Quartz de bajo nivel API de dibujo

+1

Esto está mal. – uchuugaka

9

de cacao es Graphics Core (cuarzo). Obtiene un contexto de dibujo y emite comandos para dibujar en ese contexto. La API está diseñada para ser independiente del dispositivo (usted usa los mismos comandos para dibujar en la pantalla que dibujar en papel, al imprimir). Por lo tanto, no hay comandos para completar píxeles individuales, porque no existe un píxel en el papel. Incluso en la pantalla, su vista puede haberse transformado de alguna manera, de modo que un solo punto no se asigna a un píxel de dispositivo único.

Si desea dibujar un solo píxel, debe especificar un rectángulo que tenga el tamaño de un único píxel y luego completarlo. Para el píxel en (x, y), desea un rectángulo con origen de (x-0.5, y-0.5) y un tamaño de (1,1).

Puede hacerlo con NSBezierPath, o puede obtener un contexto Core Graphics (CGContextRef) desde [[NSGraphicsContext currentContext] graphicsPort] y usar funciones como CGContextFillRect().

Esto, obviamente, no será muy rápido si está dibujando una gran cantidad de píxeles; eso no es para lo que está diseñada la API. Si eso es lo que necesita hacer, considere crear un búfer con malloc y escribir sus datos de píxel para eso, luego use Core Graphics para convertirlo en un CGImageRef, que se puede dibujar en la pantalla.

1

Tal vez estoy no entender la pregunta, pero cuarzo tiene la capacidad de llenar rectángulos:

void CGContextFillRect (CGContextRef c, CGRect rect); 
+0

O desde adentro drawRect: o un bloqueo Bloque de foco puede usar NSFillRect directamente sin obtener un CGContextRef –

3

Para la elaboración píxeles como usted la describe, no hay necesidad de crear una ruta o recurrir a la Quartz 2D o OpenGL API .

Consulte NSRectFill() y funciones relacionadas como NSRectFillList() y NSRectFillUsingOperation().

Si está dibujando muchos píxeles individuales, NSRectFillList() es lo más rápido que puede hacerlo sin tener que desplazar sus propios almacenamientos intermedios de imágenes.

0

Encontré su pregunta aquí un poco tarde porque tengo el mismo problema. Tal vez la documentación del desarrollador de Apple pueda ayudarte aquí. No he probado yo mismo, pero echa un vistazo a este documento:

http://developer.apple.com/library/mac/#documentation/cocoa/conceptual/CocoaDrawingGuide/Images/Images.html

aproximadamente en el centro del documento se encuentra la sección "Creación de un mapa de bits". Te dice diferentes formas de crear datos de píxeles.

11

Lo que se está pidiendo es cualquiera de estos dos métodos:

NSBitmapRep setColor:atX:y: cambia el color del píxel en las coordenadas especificadas.

NSBitmapRep setPixel:atX:y: Establece el píxel del receptor en las coordenadas especificadas a los valores de píxel sin procesar especificados.

Tenga en cuenta que estos no están disponibles en iOS. En iOS, parece que la forma de hacerlo es crear un búfer en bruto de datos de píxeles para un espacio de color dado (probablemente RGB), llenarlo con datos de color (escribir un pequeño método setPixel para hacer esto) y luego llamar a CGImageCreate() de este modo:

//Create a raw buffer to hold pixel data which we will fill algorithmically 
    NSInteger width = theWidthYouWant; 
    NSInteger height = theHeightYouWant; 
    NSInteger dataLength = width * height * 4; 
    UInt8 *data = (UInt8*)malloc(dataLength * sizeof(UInt8)); 

    //Fill pixel buffer with color data 
    for (int j=0; j<height; j++) { 
     for (int i=0; i<width; i++) { 

      //Here I'm just filling every pixel with red 
      float red = 1.0f; 
      float green = 0.0f; 
      float blue = 0.0f; 
      float alpha = 1.0f; 

      int index = 4*(i+j*width); 
      data[index] =255*red; 
      data[++index]=255*green; 
      data[++index]=255*blue; 
      data[++index]=255*alpha; 

     } 
    } 

    // Create a CGImage with the pixel data 
    CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, data, dataLength, NULL); 
    CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB(); 
    CGImageRef image = CGImageCreate(width, height, 8, 32, width * 4, colorspace, kCGBitmapByteOrder32Big | kCGImageAlphaPremultipliedLast, 

          provider, NULL, true, kCGRenderingIntentDefault); 

    //Clean up 
    CGColorSpaceRelease(colorspace); 
    CGDataProviderRelease(provider); 
    // Don't forget to free(data) when you are done with the CGImage 

por último, es posible que falte para manipular píxeles de una imagen que ya ha cargado en un CGImage. Hay un código de muestra para hacer eso en una Apple Technical Q & A titulada QA1509 Getting the pixel data from a CGImage object.

0

Aquí está una manera rápida para dibujar píxeles en OS X:

- (void)drawRect:(NSRect)dirtyRect { 
    [super drawRect:dirtyRect]; 

    NSBitmapImageRep *rep = [[NSBitmapImageRep alloc] 
          initWithFocusedViewRect:dirtyRect]; 

    for (int x = 0; x < [rep pixelsWide]; x++) { 
     for (int y = 0; y < [rep pixelsHigh]; y++) { 
      NSUInteger pixel[4] = { 0, 255, 0, 255 }; 
      [rep setPixel:pixel atX:x y:y]; 
     } 
    } 

    [rep drawInRect:dirtyRect]; 
} 
Cuestiones relacionadas