GraphicsUtils.m
author Jens Alfke <jens@mooseyard.com>
Sat Mar 08 21:04:41 2008 -0800 (2008-03-08)
changeset 0 d84d25d6cdbb
child 1 e55a17cdabd2
permissions -rw-r--r--
Initial checkin.
jens@0
     1
//
jens@0
     2
//  GraphicsUtils.m
jens@0
     3
//  MYUtilities
jens@0
     4
//
jens@0
     5
//  Copyright 2008 Jens Alfke. All rights reserved.
jens@0
     6
//
jens@0
     7
jens@0
     8
#import "GraphicsUtils.h"
jens@0
     9
jens@0
    10
jens@0
    11
@implementation NSImage (MYUtilities)
jens@0
    12
jens@0
    13
jens@0
    14
- (NSSize) my_sizeOfLargestRep
jens@0
    15
{
jens@0
    16
    NSArray *reps = [self representations];
jens@0
    17
    NSSize max = {0,0};
jens@0
    18
    int i;
jens@0
    19
    for( i=[reps count]-1; i>=0; i-- ) {
jens@0
    20
        NSImageRep *rep = [reps objectAtIndex: i];
jens@0
    21
        NSSize size = [rep size];
jens@0
    22
        if( size.width > max.width || size.height > max.height ) {
jens@0
    23
            max = size;
jens@0
    24
        }
jens@0
    25
    }
jens@0
    26
    return max;
jens@0
    27
}
jens@0
    28
jens@0
    29
jens@0
    30
- (NSImage*) my_shrunkToFitIn: (NSSize) maxSize
jens@0
    31
{
jens@0
    32
    NSSize size = self.size;
jens@0
    33
    float scale = MIN( size.width/maxSize.width, size.height/maxSize.height );
jens@0
    34
    if( scale >= 1.0 )
jens@0
    35
        return self;
jens@0
    36
    
jens@0
    37
    NSSize newSize = {roundf(size.width*scale), roundf(size.height*scale)};
jens@0
    38
    NSImage *newImage = [[NSImage alloc] initWithSize: newSize];
jens@0
    39
    [newImage lockFocus];
jens@0
    40
    NSGraphicsContext *context = [NSGraphicsContext currentContext];
jens@0
    41
    [context saveGraphicsState];
jens@0
    42
    [context setImageInterpolation: NSImageInterpolationHigh];
jens@0
    43
    [self drawInRect: NSMakeRect(0,0,newSize.width,newSize.height)
jens@0
    44
            fromRect: NSMakeRect(0,0,size.width,size.height)
jens@0
    45
           operation: NSCompositeCopy fraction: 1.0f];
jens@0
    46
    [context restoreGraphicsState];
jens@0
    47
    [newImage unlockFocus];
jens@0
    48
    return [newImage autorelease];
jens@0
    49
}
jens@0
    50
jens@0
    51
jens@0
    52
- (NSData*) my_JPEGData
jens@0
    53
{
jens@0
    54
    NSImage *tiffImage = [[NSImage alloc] initWithData:[self TIFFRepresentation]];
jens@0
    55
    NSBitmapImageRep *rep = [[tiffImage representations] objectAtIndex:0];
jens@0
    56
    NSDictionary *props = [NSDictionary dictionaryWithObjectsAndKeys:
jens@0
    57
        [NSNumber numberWithFloat: 0.75f], NSImageCompressionFactor, nil];
jens@0
    58
    NSData *jpeg = [rep representationUsingType: NSJPEGFileType properties: props];
jens@0
    59
    [tiffImage release];
jens@0
    60
    return jpeg;
jens@0
    61
}
jens@0
    62
jens@0
    63
jens@0
    64
#if 0
jens@0
    65
jens@0
    66
// Adapted from Apple's CocoaCreateMovie sample
jens@0
    67
// <http://developer.apple.com/samplecode/Sample_Code/QuickTime/Basics/CocoaCreateMovie/MyController.m.htm>
jens@0
    68
static void CopyNSImageRepToGWorld(NSBitmapImageRep *imageRepresentation, GWorldPtr gWorldPtr)
jens@0
    69
{
jens@0
    70
    PixMapHandle  pixMapHandle;
jens@0
    71
    unsigned char*   pixBaseAddr;
jens@0
    72
jens@0
    73
    // Lock the pixels
jens@0
    74
    pixMapHandle = GetGWorldPixMap(gWorldPtr);
jens@0
    75
    LockPixels (pixMapHandle);
jens@0
    76
    pixBaseAddr = (unsigned char*) GetPixBaseAddr(pixMapHandle);
jens@0
    77
jens@0
    78
    const unsigned char* bitMapDataPtr = [imageRepresentation bitmapData];
jens@0
    79
jens@0
    80
    if ((bitMapDataPtr != nil) && (pixBaseAddr != nil))
jens@0
    81
    {
jens@0
    82
        int i,j;
jens@0
    83
        int pixmapRowBytes = GetPixRowBytes(pixMapHandle);
jens@0
    84
        NSSize imageSize = [imageRepresentation size];
jens@0
    85
        for (i=0; i< imageSize.height; i++)
jens@0
    86
        {
jens@0
    87
            const unsigned char *src = bitMapDataPtr + i * [imageRepresentation bytesPerRow];
jens@0
    88
            unsigned char *dst = pixBaseAddr + i * pixmapRowBytes;
jens@0
    89
            for (j = 0; j < imageSize.width; j++)
jens@0
    90
            {
jens@0
    91
                *dst++ = 0;  // X - our src is 24-bit only
jens@0
    92
                *dst++ = *src++; // Red component
jens@0
    93
                *dst++ = *src++; // Green component
jens@0
    94
                *dst++ = *src++; // Blue component
jens@0
    95
            }
jens@0
    96
        }
jens@0
    97
    }
jens@0
    98
    UnlockPixels(pixMapHandle);
jens@0
    99
}
jens@0
   100
jens@0
   101
jens@0
   102
- (NSData*) my_PICTData
jens@0
   103
{
jens@0
   104
    // Locate the bitmap image rep:
jens@0
   105
    NSBitmapImageRep *rep;
jens@0
   106
    NSEnumerator *e = [[self representations] objectEnumerator];
jens@0
   107
    while( (rep=[e nextObject]) != nil ) {
jens@0
   108
        if( [rep isKindOfClass: [NSBitmapImageRep class]] )
jens@0
   109
            break;
jens@0
   110
    }
jens@0
   111
    if( ! rep ) {
jens@0
   112
        Warn(@"No bitmap image rep in image");
jens@0
   113
        return nil;
jens@0
   114
    }
jens@0
   115
jens@0
   116
    // Copy the image data into a GWorld:
jens@0
   117
    Rect bounds;
jens@0
   118
    SetRect(&bounds, 0,0,[rep pixelsWide],[rep pixelsHigh]);    
jens@0
   119
    GWorldPtr gworld;
jens@0
   120
    OSStatus err = NewGWorld(&gworld, 32, &bounds, NULL, NULL, 0);
jens@0
   121
    if( err ) {
jens@0
   122
        Warn(@"NewGWorld failed with err %i",err);
jens@0
   123
        return nil;
jens@0
   124
    }
jens@0
   125
    CopyNSImageRepToGWorld(rep,gworld);
jens@0
   126
jens@0
   127
    // Draw the GWorld into a PicHandle:
jens@0
   128
    CGrafPtr oldPort;
jens@0
   129
    GDHandle oldDevice;
jens@0
   130
    GetGWorld(&oldPort,&oldDevice);
jens@0
   131
    SetGWorld(gworld,NULL);
jens@0
   132
    ClipRect(&bounds);
jens@0
   133
    PicHandle pic = OpenPicture(&bounds);
jens@0
   134
    CopyBits(GetPortBitMapForCopyBits(gworld),
jens@0
   135
             GetPortBitMapForCopyBits(gworld),
jens@0
   136
             &bounds,&bounds,srcCopy,NULL);
jens@0
   137
    ClosePicture();
jens@0
   138
    err = QDError();
jens@0
   139
    SetGWorld(oldPort,oldDevice);
jens@0
   140
    DisposeGWorld(gworld);
jens@0
   141
    
jens@0
   142
    if( err ) {
jens@0
   143
        Warn(@"Couldn't convert to PICT: error %i",err);
jens@0
   144
        return nil;
jens@0
   145
    }
jens@0
   146
jens@0
   147
    // Copy the PicHandle into an NSData:
jens@0
   148
    HLock((Handle)pic);
jens@0
   149
    //Test to put PICT on clipboard:
jens@0
   150
    /*ScrapRef scrap;
jens@0
   151
    GetCurrentScrap(&scrap);
jens@0
   152
    ClearScrap(&scrap);
jens@0
   153
    PutScrapFlavor(scrap,'PICT',0,GetHandleSize((Handle)pic),*pic);*/
jens@0
   154
    NSData *data = [NSData dataWithBytes: *pic length: GetHandleSize((Handle)pic)];
jens@0
   155
    DisposeHandle((Handle)pic);
jens@0
   156
    Log(@"Converted image to %i bytes of PICT data",[data length]);
jens@0
   157
    return data;
jens@0
   158
}
jens@0
   159
#endif
jens@0
   160
jens@0
   161
jens@0
   162
@end
jens@0
   163
jens@0
   164
jens@0
   165
jens@0
   166
jens@0
   167
@implementation NSBezierPath (MYUtilities)
jens@0
   168
jens@0
   169
+ (NSBezierPath*) my_bezierPathWithRoundRect: (NSRect)rect radius: (float)radius
jens@0
   170
{
jens@0
   171
    radius = MIN(radius, floorf(rect.size.width/2));
jens@0
   172
    float x0 = NSMinX(rect), y0 = NSMinY(rect),
jens@0
   173
          x1 = NSMaxX(rect), y1 = NSMaxY(rect);
jens@0
   174
    NSBezierPath *path = [NSBezierPath bezierPath];
jens@0
   175
    
jens@0
   176
    [path moveToPoint: NSMakePoint(x0+radius,y0)];
jens@0
   177
    
jens@0
   178
    [path appendBezierPathWithArcFromPoint: NSMakePoint(x1,y0)
jens@0
   179
                                   toPoint: NSMakePoint(x1,y1) radius: radius];
jens@0
   180
    [path appendBezierPathWithArcFromPoint: NSMakePoint(x1,y1)
jens@0
   181
                                   toPoint: NSMakePoint(x0,y1) radius: radius];
jens@0
   182
    [path appendBezierPathWithArcFromPoint: NSMakePoint(x0,y1)
jens@0
   183
                                   toPoint: NSMakePoint(x0,y0) radius: radius];
jens@0
   184
    [path appendBezierPathWithArcFromPoint: NSMakePoint(x0,y0)
jens@0
   185
                                   toPoint: NSMakePoint(x1,y0) radius: radius];
jens@0
   186
    [path closePath];
jens@0
   187
    return path;
jens@0
   188
}
jens@0
   189
jens@0
   190
@end