Re: How to detect a Retina Mac
Re: How to detect a Retina Mac
- Subject: Re: How to detect a Retina Mac
- From: Lee Ann Rucker <email@hidden>
- Date: Sun, 18 Aug 2013 11:07:43 -0700 (PDT)
- Thread-topic: How to detect a Retina Mac
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" <email@hidden>
To: "Tom Davie" <email@hidden>
Cc: "Cocoa Dev List" <email@hidden>
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 <email@hidden> wrote:
>
> On 18 Aug 2013, at 15:56, Gerriet M. Denkmann <email@hidden> wrote:
>
>>
>> On 18 Aug 2013, at 20:09, Tom Davie <email@hidden> wrote:
>>
>>>
>>> On 18 Aug 2013, at 15:03, Gerriet M. Denkmann <email@hidden> 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 (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