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 protected]>
To: "Tom Davie" <[email protected]>
Cc: "Cocoa Dev List" <[email protected]>
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 protected]> wrote:
>
> On 18 Aug 2013, at 15:56, Gerriet M. Denkmann <[email protected]> wrote:
>
>>
>> On 18 Aug 2013, at 20:09, Tom Davie <[email protected]> wrote:
>>
>>>
>>> On 18 Aug 2013, at 15:03, Gerriet M. Denkmann <[email protected]> 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 protected])
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 [email protected]
_______________________________________________
Cocoa-dev mailing list ([email protected])
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 [email protected]