Re: NSImage/NSImageView opacity
Re: NSImage/NSImageView opacity
- Subject: Re: NSImage/NSImageView opacity
- From: "Ken Ferry" <email@hidden>
- Date: Thu, 23 Oct 2008 20:11:48 -0700
On Thu, Oct 23, 2008 at 6:20 PM, Randall Meadows <email@hidden> wrote:
>
> I'm doing some custom drawing in a custom view, but I need to capture that in a reflected image. So in that custom view's subclassed -drawRect:, I'm creating an NSImage, locking focus on that, doing all my drawing, then unlock focus. I then draw that image as the contents of the view, and use that image in my reflection view. It's all working perfectly, except...
>
> The custom drawing doesn't fill up all the contents of the bounds of the view. Specifically, a black border is left around the outside of where I'm drawing. You can view a snapshot of what I'm talking about at <http://www.not-pc.com/ViewBorder.png> (that's the top-right corner of the custom view); the blue is the background, the gray is the contents of the view I'm drawing, and the black is what I'd like to get rid of (the blue background should show through).
>
> I *thought* the trick to doing this was to use clearColor, so I do this right after I create the NSImage and lock focus on it:
>
> [[NSColor clearColor] set];
> [NSBezierPath fillRect:[self bounds]];
Hm, this is a popular mistake lately!
The behavior of -[NSBezierPath fillRect:] depends on the compositing
operation set in the context (-[NSGraphicsContext
compositingOperation]). Filling without setting a compositing
operation is similar to filling without setting a color first - the
behavior is not reliable.
In this case, you are looking to _replace_ the color in the context
with clear, as opposed to draw your color over top of what's already
there. This means that NSCompositeCopy is the appropriate operation,
as opposed to NSCompositeSourceOver. NSCompositeSourceOver is correct
if you want to draw over what's already there respecting the
transparency of the new drawing (which in this case would have no
effect on the color, since the color drawn is completely clear).
Ways one could do this:
(1) use -[NSGraphicsContext setCompositingOperation:] before drawing
with NSBezierPath
(2) use NSRectFillUsingOperation, which takes the compositing
operation explicitly
(3) use NSRectFill, which is the same as NSRectFillUsingOperation with
NSCompositeCopy (<- this is usually a pitfall! NSCompositeSourceOver
is the correct mode more often than NSCompositeCopy is)
(4) use NSEraseRect, which doesn't require setting the clear color
first either. :-)
However.. I also wonder if this might not be the problem. An NSImage
should start out clear when you lock focus on it, so I might guess
that the drawRect: method has _other_ code that is implicitly relying
on a compositing mode, and is expecting but not getting
NSCompositeSourceOver.
Or, it's possible that the image is formed correctly, but is
eventually drawn an incorrect mode. You want the image blended with
whatever it's drawn on in the normal way - NSCompositeSourceOver.
Last, you might be interested in -[NSView
cacheDisplayInRect:toBitmapImageRep:] as an alternate way of
accomplishing the end goal. Take a gander at the 10.4 AppKit release
notes, that have an explanatory section on this method. Search for
"NSView Drawing Redirection API" at
<http://developer.apple.com/releasenotes/Cocoa/AppKitOlderNotes.html>.
-Ken
Cocoa Frameworks
>
> (I create the image the same size as the view itself, so using [self bounds] should be correct, no?)
>
> I *also* fill the view itself with the clearColor in a similar manner before I blast the image into it, but none of this is working. I've also mucked about with returning YES and NO from -isOpaque:, but that didn't make a difference either.
>
> What am I missing to make my image transparent where I don't actually draw anything?
>
>
> Thanks!
> randy
> _______________________________________________
>
> Cocoa-dev mailing list (email@hidden)
>
> Please do not post admin requests or moderator comments to the list.
> Contact the moderators at cocoa-dev-admins(at)lists.apple.com
>
> Help/Unsubscribe/Update your Subscription:
>
> This email sent to email@hidden
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden