Re: Generic Bitmap to NSImage
Re: Generic Bitmap to NSImage
- Subject: Re: Generic Bitmap to NSImage
- From: Ken Thomases <email@hidden>
- Date: Thu, 25 Jun 2015 18:32:18 -0500
> On Jun 25, 2015, at 6:10 PM, Raglan T. Tiger <email@hidden> wrote:
>
> I have a list of generic bitmaps that are to be transformed to NSImages. The list can be long, I haven limits on it.
>
> Here is the code I use to populate an NSMenu that gets set into an NSPopUpButton.
>
> I need to speed this process up ... any suggestions?
>
> NSMenu *comboMenu = [[[NSMenu alloc] init] autorelease];
> POSITION pos = listOfBBitmaps.GetHeadPosition();
> while ( pos )
> {
> BBitmap *image = &listOfBBitmaps.GetNext ( pos );
>
> CGColorSpaceRef colorSpace;
> colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
> CGContextRef context;
> context = CGBitmapContextCreate (image->m_array, image->m_pixelsx, image->m_pixelsy, 8, image->m_pixelsx * 4, colorSpace, kCGImageAlphaNoneSkipFirst|kCGBitmapByteOrder32Host);
>
> CGImageRef cgImage = CGBitmapContextCreateImage (context);
>
> CGContextRelease(context);
> CGColorSpaceRelease(colorSpace);
>
> size_t width = CGImageGetWidth( cgImage );
> size_t height = CGImageGetHeight( cgImage );
> NSRect imageRect = NSMakeRect(0, 0, width, height);
> NSImage *nsImage = [[[NSImage alloc] initWithSize:imageRect.size] autorelease];
>
> if ( [nsImage respondsToSelector:@selector(lockFocusFlipped:)] )
> {
> [nsImage lockFocusFlipped:YES];
> }
> else
> {
> [nsImage setFlipped:YES];
> [nsImage lockFocus];
> }
> CGContextRef imageContext = (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort];
> CGContextDrawImage(imageContext, *(CGRect*)&imageRect, cgImage);
>
> [nsImage unlockFocus];
>
> NSMenuItem *menuItem = [[[NSMenuItem alloc] init] autorelease];
> [menuItem setImage: nsImage];
>
> [menuItem setTitle:[NSString stringWithFormat:@"untitled"]];
>
> [comboMenu addItem:menuItem];
>
> m_imageCount++;
>
> }
First suggestion is to cache the results so you don't have to convert every time.
Second is to start the process in the background as soon as you think you'll need the images rather than doing it synchronously.
Third is to avoid using drawing to create the NSImage. There are two separate approaches:
1) Create the image by creating an NSBitmapImageRep from the bitmap data and then creating an NSImage and adding that rep to it. You would call -initWithBitmapDataPlanes:pixelsWide:pixelsHigh:bitsPerSample:samplesPerPixel:hasAlpha:isPlanar:colorSpaceName:bitmapFormat:bytesPerRow:bitsPerPixel: to create the NSBitmapImageRep. You would use -initWithSize: to create the NSImage. You would add the image rep to the image using -addRepresentation:.
2) Create a CGImage using CGImageCreate(). Create an NSImage using -initWithCGImage:size:.
I doubt there's significant performance difference between the two methods, so choose whichever seems most natural.
Regards,
Ken
_______________________________________________
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