オフラインで使うBitmapバッファを作る


NSImageを加工して新しい画像を作りたいときなど、オフラインでさっと使えるBitmap領域を作ります。

## 使い方例

```Objective-C

// 下記のサンプルクラスを読み込み
#import "BitmapBuffer.h"

// 初期化
BitmapBuffer *bitmapBuffer;
bitmapBuffer = [[BitmapBuffer alloc] initWithSize:NSMakeSize(640, 480)];

// 描画
// bitmapBuffer.context でコンテキストが取り出せるので、CGContextDrawなどに指定する
CGContextDrawImage(bitmapBuffer.context, NSRect, CGImage);

// 変換
NSImage *image = [bitmapBuffer NSImage];
CGImageRef cgImage = [bitmapBuffer createCGImage];

// 保存
[bitmapBuffer savePNGImageWithPath:savePath];

```



## サンプルクラス

BitmapBuffer.h

```Objective-C

#import <Foundation/Foundation.h>

@interface BitmapBuffer : NSObject {
    unsigned char *bitmap;
    CGContextRef bitmapContext;
    CGSize bitmapSize;
}

@property (readonly) CGContextRef context;

// 任意のサイズでビットマップ領域を作ります
- (id)initWithSize:(NSSize)size;

// 内容をクリアします
- (void)clearBuffer;

// ビットマップ領域のサイズを返します
- (CGSize)size;

// ビットマップの内容をCGImageとして取り出します
- (CGImageRef)createCGImage;

// ビットマップの内容をNSImageとして取り出します
- (NSImage *)NSImage;

// ビットマップの内容をPNGに保存します
- (void)savePNGImageWithPath:(NSString *)filepath;
@end

```

BitmapBuffer.m

```Objective-C
#import "BitmapBuffer.h"
@implementation BitmapBuffer
@synthesize context = bitmapContext;
#pragma mark - init / dealloc
- (id)initWithSize:(NSSize)size {
    
    self = [super init];
    if (self) {
        
        bitmapSize = NSSizeToCGSize(size);
        CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
        bitmap = malloc(bitmapSize.width * bitmapSize.height * sizeof(unsigned char) * 4);
        bitmapContext = CGBitmapContextCreate(bitmap,
                                              bitmapSize.width,
                                              bitmapSize.height,
                                              8,
                                              bitmapSize.width * 4,
                                              colorSpace,
                                              kCGImageAlphaPremultipliedFirst);
        CGColorSpaceRelease(colorSpace);
    }
    return self;
}
- (void)dealloc {
    
    free(bitmap);
    CGContextRelease(bitmapContext);
    
    [super dealloc];
}

-(void)clearBuffer {
    CGRect clearRect = CGRectMake(0, 0, bitmapSize.width, bitmapSize.height);
    CGContextClearRect(bitmapContext, clearRect);
    CGContextSetFillColorWithColor(bitmapContext, CGColorGetConstantColor(kCGColorBlack));
    CGContextFillRect(bitmapContext, clearRect);
}

- (CGSize)size {
    return bitmapSize;
}

- (CGImageRef)createCGImage {
    CGContextFlush(bitmapContext);
    CGImageRef cgImage = CGBitmapContextCreateImage(bitmapContext);
    [(id)cgImage autorelease];
    return cgImage;
}

- (NSImage *)NSImage {
    CGImageRef cgImage = [self createCGImage];
    CGSize size = CGSizeMake(CGImageGetWidth(cgImage), CGImageGetHeight(cgImage));
    NSImage *image = [[NSImage alloc] initWithCGImage:cgImage size:NSSizeFromCGSize(size)];
    return [image autorelease];
}

- (void)savePNGImageWithPath:(NSString *)filepath {
    CGImageRef cgImage = [self createCGImage];
    NSBitmapImageRep *bitmapRep = [[NSBitmapImageRep alloc] initWithCGImage:cgImage];
    NSData *bitmapData = [bitmapRep representationUsingType:NSPNGFileType
                                                 properties:nil];
    [bitmapData writeToFile:filepath atomically:YES];
    [bitmapRep release];
}
@end
```