Re: Faster way to test pixels?
Re: Faster way to test pixels?
- Subject: Re: Faster way to test pixels?
- From: "Ken Ferry" <email@hidden>
- Date: Sun, 25 May 2008 16:44:35 -0700
There are a couple of things that aren't great about looking at the
bytes in a bitmap.
(1) You need to understand bitmap formats, as others have pointed out.
(2) Getting access to raw bitmap data often means blowing away caches
throughout the graphics system. -[NSBitmapImageRep bitmapData gives
read-write access to the bytes. You should avoid taking that access
unless you genuinely need it.
The usual advice is to try drawing instead of looking at bytes. It
really isn't so different. Try this:
// since you seem to be hit testing an object of your own class, I'll
assume it has a -drawInRect:fromRect: method, similar to
-drawInRect:fromRect:operation:fraction: on NSImage. This is a method
on your class. It looks for non-zero opacity.
- (BOOL)hitTestRect:(NSRect)testRect {
uint8_t byte = 0;
CGContextRef bitmapCtx = CGBitmapContextCreate(&byte, 1, 1, 8, 1,
NULL, kCGImageAlphaOnly);
CGContextSetInterpolationQuality(bitmapCtx, kCGInterpolationLow);
NSGraphicsContext *bitmapContext = [NSGraphicsContext
graphicsContextWithGraphicsPort:bitmapCtx flipped:NO];
[NSGraphicsContext saveGraphicsState];
[NSGraphicsContext setCurrentContext:bitmapContext];
[self drawInRect:NSMakeRect(0,0,1,1) fromRect:testRect];
[NSGraphicsContext restoreGraphicsState];
CGContextRelease(bitmapCtx);
return (byte != 0);
}
This avoids creating the bits object. If you need your bits object
for other reasons, the same approach still basically applies. Take
that bitmap rep, draw it in a 1x1 context of known format, check the
pixel you drew.
Ken Ferry
Cocoa Frameworks
On Sat, May 24, 2008 at 10:55 PM, Graham Cox <email@hidden> wrote:
> Trying to squeeze a bit more speed out of certain bottlenecks in my code.
> Here's one of them:
>
> NSBitmapImageRep* bits = [self pathBitmapInRect:ir];
>
> // if any pixels in this bitmap are set, we have a
> hit.
>
> int x, y;
> unsigned pixel;
>
> for( y = 0; y < ir.size.height; ++y )
> {
> for( x = 0; x < ir.size.width; ++x )
> {
> [bits getPixel:&pixel atX:x y:y];
>
> if ( pixel < 255 )
> {
> hit = YES;
> goto endOfLoop;
> }
> }
> }
>
> endOfLoop:
>
>
> The <bits> object is a grayscale bitmap where the background is painted
> white and any set pixels are painted black. I just need to know if there are
> *any* black pixels in the image. <ir> is an NSRect which can be any size.
> The imaging method (not shown) accounts for the origin of this rect, so the
> test scans from 0,0. The purpose is to test whether a given rect intersects
> a rendered object (path), not just test a point against it.
>
> Is there any faster way of doing this than just iterating over the pixels
> like this? I can't think of anything but someone might have a bright idea.
>
> tia,
>
>
> Graham
> _______________________________________________
>
> 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