본문 바로가기

iOS개발팁

쿼츠2D 튜토리얼...2


아이폰 어플리케이션에서 그림을 그리려면 UIView 객체를 설정하고 drawRect: 메서드를 구현해야 한다. view 객체는 drawRect: 메서드를 호출하기 전에 드로잉 환경을 자동으로 구성해 놓는다. 따라서 아이폰에서는 바로 그리기를 시작할 수 있다. 자동으로 만들어진 그래픽스 컨텍스트를 얻기 위해서 UIKit 함수인 UIGraphicsGetCurrentContext 함수를 호출한다. 얻은 그래픽스 컨텍스트의 상태를 저장하고 복귀하는 것도 UIGraphicsPushContext / UIGraphicsPopContext 함수로 가능하다.

뷰 이외에 다른 곳에 그림을 그리고자 할 때 커스텀 그래픽스 컨텍스트 객체를 생성할 수 있다. 컨텍스트를 생성하기 위해서 CGBitmapContextCreate 또는 CGPDFContextCreate 류의 함수를 사용한다. 컨텍스트를 생성한 후에는 컨텍스트를 드로잉 함수에 전달하여 그리기를 할 수 있다.

아이폰에서 주의할 것은 커스텀 컨텍스트를 생성했을 때 이 컨텍스트의 좌표계가 아이폰OS에서 사용하는 기본 좌표계와 다르다는 것이다. 좌표계의 원점이 좌상측이 아니라 좌하측이며 y 좌표는 위쪽이 + 값이 된다. 따라서 y값을 뒤집어야 하는 변환(플립핑)이 필요하다. 이 것은 CTM의 y축 값에 -1 을 곱하고 원점을 좌하측에서 좌상측으로 이동해야 한다.

만 약 CGImageRef 를 감싸고 있는 UIImage를 사용한다면 원점 변환을 할 필요는 없다. UIImage 가 내부에서 수행한다.

박스그리기

 - (void)drawRect:(CGRect)rect
{
    //컨텍스트 얻기
    CGContextRef context = UIGraphicsGetCurrentContext();
   
    //박스 그리기
    CGContextSetRGBFillColor(context, 1, 0, 0, 1);
    CGContextFillRect(context, CGRectMake(0, 0, 200, 100));
    CGContextSetRGBFillColor(context, 0, 0, 1, 0.5);
    CGContextFillRect(context, CGRectMake(0, 0, 100, 200));
}




좌표계 변경

- (void)drawRect:(CGRect)rect
{
    //컨텍스트 얻기
    CGContextRef context = UIGraphicsGetCurrentContext();
    
    //원점 좌표계 이동
    CGContextTranslateCTM(context, 0, self.bounds.size.height);
    CGContextScaleCTM(context, 1.0, -1.0);
    
    //박스 그리기
    CGContextSetRGBFillColor(context, 1, 0, 0, 1);
    CGContextFillRect(context, CGRectMake(0, 0, 200, 100));
    CGContextSetRGBFillColor(context, 0, 0, 1, 0.5);
    CGContextFillRect(context, CGRectMake(0, 0, 100, 200));
}



비트맵컨텍스트 만들기

/**
 너비와 높이를 갖는 비트맵컨텍스트를 만들어 반환한다.
 */
CGContextRef createBitmapContext(int pixelsWide, int pixelsHigh)
{
    CGContextRef context = NULL;
    CGColorSpaceRef colorSpace;
    void *bitmapData;
    int bitmapByteCount;
    int bitmapBytesPerRow;
    
    bitmapBytesPerRow = (pixelsWide * 4); //RGBA8
    bitmapByteCount = (bitmapBytesPerRow * pixelsHigh);
   
    //CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
    //은 아이폰에서 사용 불가
    colorSpace = CGColorSpaceCreateDeviceRGB();
    bitmapData = malloc(bitmapByteCount);
    if(bitmapData == NULL)
    {
        NSLog(@"Memory not allocated!");
        return NULL;
    }
    
    context = CGBitmapContextCreate(
                                    bitmapData,
                                    pixelsWide,
                                    pixelsHigh,
                                    8, //bits per color component
                                    bitmapBytesPerRow,
                                    colorSpace,
                                    kCGImageAlphaPremultipliedLast);
    
    if(context == NULL)
    {
        free(bitmapData);
        NSLog(@"Context not created!");
        return NULL;
    }
    CGColorSpaceRelease(colorSpace);
    return context;
}

- (void)drawRect:(CGRect)rect
{
    //비트맵 컨텍스트 얻기
    CGContextRef bitmapContext = createBitmapContext(320, 460);
   
   
    //원점 좌표계 이동
    CGContextTranslateCTM(bitmapContext, 0, self.bounds.size.height);
    CGContextScaleCTM(bitmapContext, 1.0, -1.0);
   
    //박스 그리기
    CGContextSetRGBFillColor(bitmapContext, 1, 0, 0, 1);
    CGContextFillRect(bitmapContext, CGRectMake(0, 0, 200, 100));
    CGContextSetRGBFillColor(bitmapContext, 0, 0, 1, 0.5);
    CGContextFillRect(bitmapContext, CGRectMake(0, 0, 100, 200));
   
    //비트맵을 이미지로 변경(렌더링)하기
    CGImageRef bitmapImage = CGBitmapContextCreateImage(bitmapContext);
   
    //이미지를 뷰에 그리기
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextDrawImage(context, CGRectMake(0, 0, 320, 460), bitmapImage);
   
    //자원메모리 해지하기
    char *bitmapData = CGBitmapContextGetData(bitmapContext);
    if(bitmapData)
        free(bitmapData);
    CGContextRelease(bitmapContext);
    CGImageRelease(bitmapImage);
}



안티앨리어싱


컨텍스트의 그래픽스 상태로 CGContextSetShouldAntialias(context, true or false); 함수로 설정을 켜거나 끈다.



'iOS개발팁' 카테고리의 다른 글

SIO2와 Blender를 만나다.  (2) 2010.06.14
아이폰, 사용가능한 장치 확인하기.  (2) 2010.06.14
쿼츠2D 튜토리얼...1  (0) 2010.05.18
맥에서 화면 캡쳐하기  (0) 2010.05.12
테두리가 둥근 UITextView 만들기.  (0) 2010.05.10