2010-12-04 3 views
9

J'aimerais trouver une réponse pour ça. J'ai cherché et cherché et ne pouvais pas la bonne réponse. Voici ma situation:Mac OS Cocoa: Dessine un simple pixel sur une toile

Dans une application Mac OS Cocoa, je souhaite dessiner un pixel (en fait quelques pixels) sur une zone dédiée de ma fenêtre d'application. Je me suis dit, il serait plus agréable d'avoir un NSImageView placé là (je l'ai fait avec IB et connecté la sortie à mon délégué de l'application) et dessiner sur ce à la place de mon NSWindow.

Comment puis-je faire cela dans le monde? Mac OS semble offrir NSBezierPath comme l'outil de dessin le plus basique — est-ce vrai? C'est complètement choquant pour moi. Je viens d'une longue histoire de programmation Windows et dessiner un pixel sur une toile est la chose la plus simple, typiquement.

Je ne veux pas utiliser OpenGL et je ne suis pas sûr de savoir dans quelle mesure Quartz est impliqué dans cela.

Tout ce que je veux est une aide sur la façon dont je peux retirer cette pseudo-code en temps réel Objective-C/Cocoa:

imageObj.drawPixel(10,10,blackColor); 

J'aimerais entendre vos réponses à ce sujet et je suis sûr que cela va aider beaucoup de gens commençant par Cocoa.

Merci!

Répondre

-12

NSBezierPath est le seul outil disponible dans Cocoa pour dessiner les formes les plus primitives, et pour beaucoup de formes complexes. Description détaillée vous pouvez trouver ici: 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

+1

Ceci est tout simplement faux. – uchuugaka

9

API de dessin à faible niveau de cacao est de base graphique (Quartz). Vous obtenez un contexte de dessin et lancez des commandes pour dessiner sur ce contexte. L'API est conçue pour être indépendante des périphériques (vous utilisez les mêmes commandes pour dessiner sur l'écran que vous dessinez sur papier, lors de l'impression). Par conséquent, il n'y a pas de commandes pour remplir des pixels individuels, car il n'y a pas de pixel sur papier. Même sur l'écran, votre vue a peut-être été transformée d'une manière ou d'une autre, de sorte qu'un seul point ne correspond pas à un seul pixel de périphérique. Si vous voulez dessiner un seul pixel, vous devez spécifier un rectangle de la taille d'un seul pixel, puis le remplir. Pour le pixel à (x, y), vous voulez un rectangle avec l'origine de (x-0,5, y-0,5) et une taille de (1,1).

Vous pouvez le faire avec NSBezierPath, ou vous pouvez obtenir un contexte Core Graphics (CGContextRef) de [[NSGraphicsContext currentContext] graphicsPort] et utiliser des fonctions comme CGContextFillRect().

Cela ne sera évidemment pas très rapide si vous dessinez beaucoup de pixels; ce n'est pas ce à quoi l'API est destinée. Si c'est ce que vous devez faire, pensez à créer un tampon avec malloc et en écrivant vos données de pixels, puis en utilisant Core Graphics pour le convertir en un CGImageRef, qui peut être dessiné à l'écran.

1

Peut-être que je suis malentendu la question, mais Quartz a la capacité de remplir des rectangles:

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

Ou à partir de drawRect: ou un bloc lockFocus vous pouvez directement utiliser NSFillRect sans obtenir un CGContextRef –

3

Pour dessiner des pixels que vous décrivez, il n'y a pas besoin de créer un chemin d'accès ou recours à l'API 2D Quartz ou OpenGL .

Voir NSRectFill() et les fonctions connexes comme NSRectFillList() et NSRectFillUsingOperation().

Si vous dessinez beaucoup de pixels individuels, NSRectFillList() est à peu près aussi rapide que possible sans avoir à rouler vos propres tampons d'image.

0

J'ai trouvé votre question ici un peu en retard parce que j'ai le même problème. Peut-être la documentation du développeur Apples peut vous aider ici. Je ne l'ai pas testé moi-même, mais jetez un oeil à ce document:

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

à peu près au centre du document, vous trouverez la section « Création d'une Bitmap ». Il vous indique différentes façons de créer des données de pixels.

11

Ce que vous demandez est l'une de ces deux méthodes:

NSBitmapRep setColor:atX:y: change la couleur du pixel aux coordonnées spécifiées.

NSBitmapRep setPixel:atX:y: Définit le pixel du récepteur aux coordonnées spécifiées aux valeurs de pixels brutes spécifiées.

Notez que ceux-ci ne sont pas disponibles sur iOS. Sur iOS, il semble que la manière de faire ceci est de créer un tampon brut de données de pixels pour un espace de couleurs donné (RGB probable), remplir avec des données de couleur (écrire une petite méthode setPixel pour cela) et ensuite appeler CGImageCreate() comme ceci:

//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 

Enfin, vous manquât de manipuler les pixels dans une image que vous avez déjà chargé dans un CGImage. Il existe un exemple de code pour cela dans un Apple Technical Q & A intitulé QA1509 Getting the pixel data from a CGImage object.

0

est ici un moyen rapide de dessiner des pixels sur 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]; 
} 
Questions connexes