▼iPhoneプログラミングメモ▼
Quartによる2Dグラフィックス


Quartによる2Dグラフィックスの描画を行うプログラムを作成する。


フレームワークの準備
QuartzCoreフレームワークを追加。

画像の準備

pic0.png

pig1.png


ソースコードの記述

GraphicsQCEx.h
#import <UIKit/UIKit.h>
#import "GraphicsQC.h"

//GraphicsQCExの宣言
@interface GraphicsQCEx : UIView {
    GraphicsQC* _g;     //グラフィックス
    UIImage*    _image0;//イメージ0
    UIImage*    _image1;//イメージ1
}
@end

GraphicsQCEx.m
#import "GraphicsQCEx.h"

//GraphicsQCExの実装
@implementation GraphicsQCEx

//フレームの初期化
- (id)initWithFrame:(CGRect)frame {
    if (self=[super initWithFrame:frame]) {
        //グラフィックスの生成
        _g=[[GraphicsQC alloc] init];
        
        //イメージの読み込み
        _image0=[[UIImage imageNamed:@"pic0.png"] retain];
        _image1=[[UIImage imageNamed:@"pic1.png"] retain];
    }
    return self;
}

//メモリ解放
- (void)dealloc {
    [_g release];
    [_image0 release];
    [_image1 release];
    [super dealloc];
}

//描画
- (void)drawRect:(CGRect)rect {
    //コンテキストの指定
    [_g setContext:UIGraphicsGetCurrentContext()];

    //バッファのクリア
    [_g setColorR:1 g:1 b:1];
    [_g fillRectX:0 y:0 w:320 h:640];
     
    //画像の描画    
    [_g drawImage:_image0 x:20 y:20];
    [_g drawImage:_image1 x:150 y:20];

    //文字列の描画
    [_g setColorR:0 g:0 b:1];
    [_g setFont:[UIFont boldSystemFontOfSize:24]];
    [_g drawString:@"そらみ" x:180 y:20];
    
    //ラインの描画
    [_g setColorR:0 g:0 b:255];
    [_g setLineWidth:2];
    [_g drawLineX0:80 y0:160 x1:80 y1:260];

    //パスの描画
    float dx[]={170,190,210,230,250,270};
    float dy[]={160,260,160,260,160,260};
    [_g setColorR:255 g:0 b:0];
    [_g setLineWidth:3];
    [_g drawPolylineX:dx y:dy length:6];
    
    //矩形の描画
    [_g setColorR:0 g:255 b:0];
    [_g setLineWidth:1];
    [_g drawRectX:20 y:280 w:60 h:60];
    
    //矩形の塗り潰し
    [_g setColorR:255 g:255 b:0];
    [_g setLineWidth:1];
    [_g fillRectX:100 y:280 w:60 h:60];
    
    //円の描画
    [_g setColorR:0 g:255 b:0];
    [_g drawCircleX:200 y:310 r:30];

    //円の塗り潰し
    [_g setColorR:0 g:0 b:255];
    [_g fillCircleX:270 y:310 r:30];
}
@end

便利クラス

GraphicsQC.h
#import <UIKit/UIKit.h>

//GraphicsQCの宣言
@interface GraphicsQC : NSObject {
    CGContextRef   _context;   //コンテキスト
    unsigned char* _contextBMP;//コンテキストBMP
	UIFont*        _font;      //フォント
}

//コンテキスト
- (void)setContext:(CGContextRef)context;
- (void)makeContext:(CGSize)size;
- (void)releaseContext;
- (void)pushContext;
- (void)popContext;
- (UIImage*)makeScreenShot;

//アクセス
- (void)setLineWidth:(float)lineWidth;
- (void)setColorR:(float)r g:(float)g b:(float)b a:(float)a;
- (void)setColorR:(float)r g:(float)g b:(float)b;
- (void)setLineWidth:(float)lineWidth;
- (void)setFont:(UIFont*)font;
- (void)setTranslateX:(float)transX y:(float)transY;
- (void)setRotate:(float)rotate;
- (void)setScaleW:(float)scaleW h:(float)scaleH;
- (void)clipRectX:(float)x y:(float)y w:(float)w h:(float)h;
- (void)pushMatrix;
- (void)popMatrix;

//描画
- (void)drawLineX0:(float)x0 y0:(float)y0 x1:(float)x1 y1:(float)y1;
- (void)drawPolylineX:(float[])x y:(float[])y length:(int)length;
- (void)drawPolyline:(CGPoint[])vertex length:(int)length;
- (void)drawPolyline:(CGMutablePathRef)line;
- (void)drawRectX:(float)x y:(float)y w:(float)w h:(float)h;
- (void)fillRectX:(float)x y:(float)y w:(float)w h:(float)h;
- (void)drawCircleX:(float)x y:(float)y r:(float)r;
- (void)drawCircleX:(float)x y:(float)y w:(float)w h:(float)h;
- (void)fillCircleX:(float)x y:(float)y r:(float)r;
- (void)fillCircleX:(float)x y:(float)y w:(float)w h:(float)h;
- (void)drawTriangle:(CGPoint[])pos;
- (void)fillTriangle:(CGPoint[])pos;
- (void)drawImage:(UIImage*)image x:(float)x y:(float)y;
- (void)drawImage:(UIImage*)image x:(float)x y:(float)y w:(float)w h:(float)h;
- (void)drawString:(NSString*)string x:(float)x y:(float)y;
@end

GraphicsQC.m
#import "GraphicsQC.h"

//GraphicsQCの実装
@implementation GraphicsQC

//====================
//初期化
//====================
//初期化
- (id)init {
    if (self=[super init]) {
        _context=NULL;
        _contextBMP=NULL;
        _font=[UIFont boldSystemFontOfSize:12];
    }
    return self;
}

//メモリ解放
- (void)dealloc {
    [self releaseContext];
    [super dealloc]; 
}

//====================
//コンテキスト
//====================
//コンテキストの指定
- (void)setContext:(CGContextRef)context {
    //コンテキストの解放
    [self releaseContext];
    
    //コンテキストの指定
    _context=context;
    CGContextRetain(_context);
}

//コンテキストの生成
- (void)makeContext:(CGSize)size {
    //コンテキストの解放
    [self releaseContext];

    //コンテキストの生成
    CGColorSpaceRef colorSpace=CGColorSpaceCreateDeviceRGB();
    _contextBMP=malloc(size.width*size.height*sizeof(unsigned char)*4); 
    _context=CGBitmapContextCreate(_contextBMP, 
        size.width,size.height,8,size.width*4,
        colorSpace,kCGImageAlphaPremultipliedFirst);
    if (_context==nil) {
        CGColorSpaceRelease(colorSpace);
        [self releaseContext];
        return;
    }
    CGContextClearRect(_context,CGRectMake(0,0,size.width,size.height));
    CGColorSpaceRelease(colorSpace);
}

//コンテキストの解放
- (void)releaseContext {
    if (_context!=NULL) {
        CGContextRelease(_context);
        _context=NULL;
    }
    if (_contextBMP!=NULL) {
        free(_contextBMP);
        _contextBMP=NULL;
    }
}

//コンテキストのプッシュ
- (void)pushContext {
    UIGraphicsPushContext(_context);  
}

//コンテキストのポップ
- (void)popContext {
    UIGraphicsPopContext();
}

//スクリーンショットの取得
- (UIImage*)makeScreenShot {
    CGImageRef imageRef=CGBitmapContextCreateImage(_context);
    UIImage* image=[[[UIImage alloc] initWithCGImage:imageRef] autorelease];
    CGImageRelease(imageRef);
    return image;
}

//====================
//アクセス
//====================    
//色の指定
- (void)setColorR:(float)r g:(float)g b:(float)b {
    CGContextSetRGBFillColor(_context,r,g,b,1);
    CGContextSetRGBStrokeColor(_context,r,g,b,1);
}

//色の指定
- (void)setColorR:(float)r g:(float)g b:(float)b a:(float)a {
    CGContextSetRGBFillColor(_context,r,g,b,a);
    CGContextSetRGBStrokeColor(_context,r,g,b,a);
}

//ライン幅の指定
- (void)setLineWidth:(float)lineWidth {
    CGContextSetLineWidth(_context,lineWidth);
}

//フォントの指定
- (void)setFont:(UIFont*)font {
    _font=font;
}

//平行移動の指定 
- (void)setTranslateX:(float)x y:(float)y {
    CGContextTranslateCTM(_context,x,y); 
}

//スケールの指定 
- (void)setScaleW:(float)w h:(float)h {
    CGContextScaleCTM(_context,w,h);
}

//回転の指定 
- (void)setRotate:(float)rotate {
    CGContextRotateCTM(_context,rotate); 
}

//クリッピングの指定
- (void)clipRectX:(float)x y:(float)y w:(float)w h:(float)h {
    CGContextClipToRect(_context,CGRectMake(x,y,w,h));
}

//行列のプッシュ
- (void)pushMatrix {
    CGContextSaveGState(_context);  
}

//行列のポップ
- (void)popMatrix {
    CGContextRestoreGState(_context);
}

//====================
//描画
//====================
//ラインの描画
- (void)drawLineX0:(float)x0 y0:(float)y0 x1:(float)x1 y1:(float)y1 {
    CGContextSetLineCap(_context,kCGLineCapRound);
    CGContextMoveToPoint(_context,x0,y0);
    CGContextAddLineToPoint(_context,x1,y1);
    CGContextStrokePath(_context);
}

//ポリラインの描画
- (void)drawPolylineX:(float[])x y:(float[])y length:(int)length {
    CGMutablePathRef path=CGPathCreateMutable();
    CGPathMoveToPoint(path,NULL,x[0],y[0]);
    for (int i=1;i<length;i++) {
        CGPathAddLineToPoint(path,NULL,x[i],y[i]);
    }
    [self drawPolyline:path];
    CGPathRelease(path);
}

//ポリラインの描画
- (void)drawPolyline:(CGPoint[])vertex length:(int)length {
    CGMutablePathRef path=CGPathCreateMutable();
    CGPathMoveToPoint(path,NULL,vertex[0].x,vertex[0].y);
    for (int i=1;i<length;i++) {
        CGPathAddLineToPoint(path,NULL,vertex[i].x,vertex[i].y);
    }
    [self drawPolyline:path];
    CGPathRelease(path);
}

//ポリラインの描画
- (void)drawPolyline:(CGMutablePathRef)line {
    CGContextSetLineCap(_context,kCGLineCapRound);
    CGContextSetLineJoin(_context,kCGLineJoinRound);
    CGContextAddPath(_context,line);
    CGContextDrawPath(_context,kCGPathStroke);
}

//矩形の描画
- (void)drawRectX:(float)x y:(float)y w:(float)w h:(float)h {    
    CGContextMoveToPoint(_context,x,y);
    CGContextAddLineToPoint(_context,x+w,y);
    CGContextAddLineToPoint(_context,x+w,y+h);
    CGContextAddLineToPoint(_context,x,y+h);
    CGContextAddLineToPoint(_context,x,y);
    CGContextAddLineToPoint(_context,x+w,y);
    CGContextStrokePath(_context);
}

//矩形の塗り潰し
- (void)fillRectX:(float)x y:(float)y w:(float)w h:(float)h {    
    CGContextFillRect(_context,CGRectMake(x,y,w,h));
}

//円の描画
- (void)drawCircleX:(float)x y:(float)y r:(float)r {    
    CGContextAddEllipseInRect(_context,CGRectMake(x-r,y-r,r*2,r*2));
    CGContextStrokePath(_context);
}

//円の描画
- (void)drawCircleX:(float)x y:(float)y w:(float)w h:(float)h {    
    CGContextAddEllipseInRect(_context,CGRectMake(x,y,w,h));
    CGContextStrokePath(_context);
}

//円の塗り潰し
- (void)fillCircleX:(float)x y:(float)y r:(float)r {    
    CGContextFillEllipseInRect(_context,CGRectMake(x-r,y-r,r*2,r*2));
}

//円の塗り潰し
- (void)fillCircleX:(float)x y:(float)y w:(float)w h:(float)h {    
    CGContextFillEllipseInRect(_context,CGRectMake(x,y,w,h));
}

//三角形の描画
- (void)drawTriangle:(CGPoint[])pos {
    CGContextMoveToPoint(_context,pos[0].x,pos[0].y);
    CGContextAddLineToPoint(_context,pos[1].x,pos[1].y);
    CGContextAddLineToPoint(_context,pos[2].x,pos[2].y);
    CGContextStrokePath(_context);
}

//三角形の塗り潰し
- (void)fillTriangle:(CGPoint[])pos {
    CGContextMoveToPoint(_context,pos[0].x,pos[0].y);
    CGContextAddLineToPoint(_context,pos[1].x,pos[1].y);
    CGContextAddLineToPoint(_context,pos[2].x,pos[2].y);
    CGContextFillPath(_context);
}

//イメージの描画
- (void)drawImage:(UIImage*)image x:(float)x y:(float)y {
    if (image==nil) return;    
    [image drawAtPoint:(CGPointMake(x,y))];
}

//イメージの描画
- (void)drawImage:(UIImage*)image x:(float)x y:(float)y w:(float)w h:(float)h {
    if (image==nil) return;
    [image drawInRect:(CGRectMake(x,y,w,h))];
}

//文字列の描画
- (void)drawString:(NSString*)string x:(float)x y:(float)y {
    [string drawAtPoint:CGPointMake(x,y) withFont:_font];
}
@end

  



−戻る−