7
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

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

Posted at

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

使い方例


// 下記のサンプルクラスを読み込み
# 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


# 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

# 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
7
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?