Getting to an NSWindow's pixels

Posts: 1,563
Joined: 2003.10
Post: #1
I'm kicking around a bunch of different approaches for blitting image data to a Cocoa window. My current implementation uses NSDrawBitmap, which works, but there are some situations where I'd be able to sidestep filling out a pixel array to pass to it (essentially doing an extra blit) if I could get a pointer to the window's back buffer and blit directly into it.

I hacked up a quick test that essentially did this (which worked surprisingly well):

unsigned char * windowPixels;
WindowRef windowRef;

windowRef = [myNSWindow windowRef];

windowPixels = GetPixBaseAddr(GetPortPixMap(GetWindowPort(windowRef)));

// Write to windowPixels...

QDFlushPortBuffer(GetWindowPort(windowRef), NULL);

That code will of course raise all kinds of "deprecated, unsafe, bad, etc." flags in people's heads (and the compiler), so here's my question: Is there some way to access this pointer without going through deprecated QuickDraw functions?

Also, does anyone know of a reason off the top of their head that this definitely will not work in 10.5 or some other situation in the present or near future? If it's a viable approach despite deprecation, I might be able to just go ahead and do it this way...
Quote this message in a reply
Posts: 5,143
Joined: 2002.04
Post: #2
I believe QuickDraw does not exist for 64-bit 10.5, so if you think some users of your program might want it to use more than 4GB of RAM (not completely absurd for an image editor) then you'll want to avoid it.

It's also the case that where you have window scaling going on that the pixels in the back buffer won't map 1-1 with the pixels in your image. You can test that out using Quartz Debug on 10.4, I think, though I think there may also be some minor API changes related to it in 10.5. I suspect NSDrawBitmap will work as poorly as CopyBits in this case...

My thought would be to grab the CGContext for the window, check if it's a bitmap context (and if not fall back to a less efficient method), check if it's the number of pixels wide and high you expect (and if not fall back to a less efficient method), and then do the direct blit into the CGBitmapContext's pixel buffer, which can only be in a very few different formats.
Quote this message in a reply
Posts: 1,563
Joined: 2003.10
Post: #3
Ooh, you can get a CGContext for an NSWindow? Sounds great! I'll have a look when I get home...
Quote this message in a reply
Posts: 1,563
Joined: 2003.10
Post: #4
Didn't work out as well as I'd hoped. [[NSWindow graphicsContext] graphicsPort] gives me a CGContextRef, but not a CGBitmapContextRef. I can draw into it with Quartz 2D API calls and stuff, but I can't actually get at the pixels directly. Ah well, I guess NSDrawBitmap will do well enough...
Quote this message in a reply
Post: #5
I'm trying to do something similar too, except that I don't really mind if I can't get direct access to a window's pixels, but I would like to be able to draw some sort of "offscreen" buffer to a window.

At first I thought I could use a CGImage and draw into and then draw that into a window's context, but there doesn't seem to be able a way to access the pixel of data of a CGImage because the data could be in a non-directly accessible format.

I know that the Apple's Quartz 2D guide says that people used to create a bitmap context and use that as "offscreen" buffer, but they use CGLayer now instead. I know that I can get direct pixel access of a bitmap context, but how do I then draw that context to another? Is that even possible?
Quote this message in a reply
Post Reply 

Possibly Related Threads...
Thread: Author Replies: Views: Last Post
  Best way to readback float pixels? kelvin 8 9,580 Feb 27, 2008 10:23 PM
Last Post: kelvin
  SDL Parachute Deployed when accessing surface->pixels BobbyWatson 8 9,253 Jan 23, 2005 06:30 PM
Last Post: MattDiamond
  getting pixels from a texture kelvin 16 8,811 Mar 14, 2003 05:55 PM
Last Post: Mars_999