Adapted from things I picked up at WWDC, this creates an NSImage with normal and Retina representations
@implementation NSBitmapImageRep (NSAppKitAdditions) + (NSBitmapImageRep *)imageRepWith32bitBuffer: (unsigned char *)bitmapBuffer // IN/OPT pixelsWide: (int)pixelsWide // IN pixelsHigh: (int)pixelsHigh // IN bitmapFormat: (NSBitmapFormat)bitmapFormat // IN bytesPerRow: (int)bytesPerRow // IN { NSBitmapFormat supportedFormatsMask = NSAlphaNonpremultipliedBitmapFormat | NSAlphaFirstBitmapFormat; NSBitmapImageRep *result = [[[NSBitmapImageRep alloc] initWithBitmapDataPlanes:&bitmapBuffer pixelsWide:pixelsWide pixelsHigh:pixelsHigh bitsPerSample:8 samplesPerPixel:4 hasAlpha:YES isPlanar:NO colorSpaceName:NSCalibratedRGBColorSpace bitmapFormat:bitmapFormat bytesPerRow:bytesPerRow bitsPerPixel:32] autorelease]; if (!result) { return nil; } /* * If a new buffer has been allocated (not passed in), clear the contents * to prevent garbage data from showing up in unused areas. */ if (!bitmapBuffer && [result bitmapData]) { bzero([result bitmapData], [result bytesPerRow] * [result pixelsHigh]); } return result; } + (NSBitmapImageRep *)imageRepWithSize: (NSSize)size // IN scale: (NSUInteger)scale // IN { NSBitmapImageRep *bmpImageRep = [NSBitmapImageRep imageRepWith32bitBuffer:NULL pixelsWide:size.width * scale pixelsHigh:size.height * scale bitmapFormat:0 bytesPerRow:0]; // Setting the user size communicates the dpi. [bmpImageRep setSize:size]; return bmpImageRep; } @end @implementation NSImage (NSAppKitAdditions) /* * Creates an image with high and low DPI representations. * Both representations will be set to the same size. */ + (NSImage *)imageWithSize: (NSSize)size // IN rep1: (NSImageRep *)rep1 // IN rep2: (NSImageRep *)rep2 // IN { if (rep1 == nil || rep2 == nil) { return nil; } NSImage *result = [[[NSImage alloc] initWithSize:size] autorelease]; [rep1 setSize:size]; [rep2 setSize:size]; [result addRepresentation:rep1]; [result addRepresentation:rep2]; return result; } /* * Calls the drawingBlock to generate high and low dpi images. */ + (NSImage *)imageWithSize: (NSSize)size // IN drawingBlock: (NSImageAdditions_DrawingBlock)drawingBlock // IN { NSBitmapImageRep *bitmap1x = [NSBitmapImageRep imageRepWithSize:size scale:1]; NSBitmapImageRep *bitmap2x = [NSBitmapImageRep imageRepWithSize:size scale:2]; [NSGraphicsContext saveGraphicsState]; NSGraphicsContext *bitmapContext = [NSGraphicsContext graphicsContextWithBitmapImageRep:bitmap1x]; [NSGraphicsContext setCurrentContext:bitmapContext]; drawingBlock(); bitmapContext = [NSGraphicsContext graphicsContextWithBitmapImageRep:bitmap2x]; [NSGraphicsContext setCurrentContext:bitmapContext]; drawingBlock(); [NSGraphicsContext restoreGraphicsState]; return [self imageWithSize:size rep1:bitmap1x rep2:bitmap2x]; } @end ----- Original Message ----- From: "Gerriet M. Denkmann" <gerr...@mdenkmann.de> To: "Tom Davie" <tom.da...@gmail.com> Cc: "Cocoa Dev List" <cocoa-dev@lists.apple.com> Sent: Sunday, August 18, 2013 8:16:47 AM Subject: Re: How to detect a Retina Mac On 18 Aug 2013, at 21:03, Tom Davie <tom.da...@gmail.com> wrote: > > On 18 Aug 2013, at 15:56, Gerriet M. Denkmann <gerr...@mdenkmann.de> wrote: > >> >> On 18 Aug 2013, at 20:09, Tom Davie <tom.da...@gmail.com> wrote: >> >>> >>> On 18 Aug 2013, at 15:03, Gerriet M. Denkmann <gerr...@mdenkmann.de> wrote: >>> >>>> I just noticed that the program I use to create Png files creates files >>>> with twice the number of pixels in each dimension. >>>> Obviously because since I last used it, I have switched to a Retina Mac >>>> Book. >>>> >>>> Ok, so I have to fix this program. >>> >>> The correct way to fix this problem is to create an image via >>> CGContextCreate and CGContextCreateImage. When doing this you specify >>> pixel rather than point dimensions, and do not have the issue you’re >>> experiencing. You detect a retina device by testing scaleFactor as you >>> suggested, it’s just unnecessary here. >> >> I just asked Xcode about CGContextCreate and it told me that there is >> absolutely no information available. >> Could anybody help me with some link to some documentation? > > Uhh sorry, my bad, I meant CG*Bitmap*ContextCreate… > > http://developer.apple.com/library/ios/documentation/graphicsimaging/Reference/CGBitmapContext/Reference/reference.html Ah, now I found lots of info! But I do not understand it. CIImage, CGImage, NSImage, UIImage... This is just too much for my small brain. I removed: finalWidth /= 2; // Retina Fix 18.Aug. 2013 and replaced: NSImage *image = [[NSImage alloc] initWithSize: sizE]; by: size_t pixelsWide = (size_t)sizE.width; size_t pixelsHigh = (size_t)sizE.height; size_t bitmapBytesPerRow = pixelsWide * 4; CGColorSpaceRef colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB); CGContextRef c = CGBitmapContextCreate ( NULL, pixelsWide, pixelsHigh, 8, bitmapBytesPerRow, colorSpace, (CGBitmapInfo)kCGImageAlphaPremultipliedLast); CGImageRef cgImage = CGBitmapContextCreateImage ( c ); NSImage *image = [[NSImage alloc] initWithCGImage: cgImage size: NSZeroSize ]; (ignoring leaks for the time being) ... and then continued with my old code. The png is still 100 pixels wide. You see, I am rather clueless. Kind regards, Gerriet. _______________________________________________ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) 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: https://lists.apple.com/mailman/options/cocoa-dev/lrucker%40vmware.com This email sent to lruc...@vmware.com _______________________________________________ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) 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: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com