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

Reply via email to