Re: Stumped on paint bucket in Core Image and polygons in Quartz
Re: Stumped on paint bucket in Core Image and polygons in Quartz
- Subject: Re: Stumped on paint bucket in Core Image and polygons in Quartz
- From: Scott Thompson <email@hidden>
- Date: Sun, 12 Jun 2005 10:59:20 -0700
On Jun 12, 2005, at 8:18 AM, Nicko van Someren wrote:
On 12 Jun 2005, at 06:11, Chilton Webb wrote:
I've been playing with the example Core Image Micro Paint. My
understanding of Quartz leave much to be desired though. How would
I go about implementing a seed fill, like the paint bucket tool in
Photoshop?
I don't think that Quartz provides this sort of fill operation as a
primitive. You will likely have to implement the Flood Fill
algorithm yourself. Google for various discussions of the
algorithm; it's fairly basic. If you want to do anything cute like
flood fill using a pattern I suggest you us a stack based rather
than a recursive version, produce a rendition of the fill area into
a mask image and then use this to stencil in your fill pattern.
While I suggest you initially implement the algorithms to be
correct and only subsequently profile the code and optimise its
performance, I suggest you think carefully about your routine for
testing if a pixel is inside the fill area or not. It will be
called at least once for every pixel inside the area and once for
every pixel on the edge. My past experience showed that it's easy
for any function/method call overhead for this to dwarf the actual
cost of the test, but since it will be entirely implementation
dependent there is no substitute for profiling.
Expanding on Niko's reply...
As you move from QuickDraw to Quartz, one of the hardest things to
get used to is the idea that graphics are no longer made up of pixels
any more.
Pixels are a device-dependent concept. Not every device has pixels.
For example, a PostScript printer accepts a stream of drawing
commands. More likely than not, the PostScript interpreter in the
printer is going to translate those commands into a frame buffer of
some kind... but the public interface to the printer, the printer as
seen from the outside, has no pixels. The advantage of this setup is
that the drawing is no longer being done at a fixed resolution. The
conversion to pixels (if necessary) is the last step of the drawing
process which means that the conversion can be done at the full
resolution of the destination.
Even in the case where you are presenting a pixel-based image to
Quartz, it really doesn't treat it as pixels per-se. It treats it as
a rectangular array of color samples. When you draw the image in a
Quartz context, the computer resamples the image and (if you're
drawing to a pixel-base device) generates pixels based on that
resampling. In short, it treats the image as a resolution
independent tiling of color samples and generate the pixels from it
(on pixel base devices).
Your seed fill, or flood fill, is a pixel level operation. It is
very device dependent. To make it work through Quartz, you are going
to want to take your drawing to a pixel device (like an offscreen
bitmap) and perform the flood fill in that environment.
Unfortunately, once you have done so, you're going to be limiting the
resolution of your image.
This concept, that you are no longer drawing to the pixels, is a
very, very difficult concept for QuickDraw programmers to get used
to. So much of the investment in learning QuickDraw centers around
understanding how to manipulate pixels very efficiently. Many of the
optimization techniques programs use to speed up drawing for
QuickDraw follow in the same lines. Given the way that Quartz 2D
separates the act of drawing, from the act of generating a pixel
image, lots of traditional QuickDraw drawing optimizations, like
caching off large images, can actually wind up being detrimental to
performance on Quartz 2D.
Also, where can I find examples of creating polygons in Quartz?
See the section on Paths in the Quartz 2D Programming Guide:
http://developer.apple.com/documentation/GraphicsImaging/Conceptual/
drawingwithquartz2d/
Quartz 2D doesn't have Polygons as an explicit primitive. Instead
you create paths using either CGContextMoveToPoint and
CGContextAddLineToPoint or CGPathMoveToPoint and
CGPathAddLineToPoint. If you want to store a polygon in an explicit
polygon representation then you are going to have to create, and
maintain, your own structure.
Scott
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Cocoa-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden