2016-11-22 7 views
1

У меня есть изображение руки часов. Я пытаюсь создать повернутые версии этого изображения, чтобы Ic воспроизводил его с использованием анимации (используя метод UIImageView'sanimatedImages).Как нарисовать UIImage с помощью drawAtPoint после перевода графического контекста изображения

В приведенном ниже коде я вижу, что если я применил CGContextTranslateCTM к контексту графической графики, изображение не будет нарисовано, если я не увеличу размер, который я даю UIGraphicsBeginImageContextWithOptions, чтобы сделать его больше, чем размер изображения.

Зачем это необходимо? Я бы подумал, что весь перевод состоит в том, чтобы переместить определение того, как drawAtPoint: интерпретирует, где 0,0 есть?

** Edited код показывает более подробную информацию *

-(void) animatedClock 
{ 
    UIGraphicsBeginImageContextWithOptions(CGSizeMake(20, 100), NO, 0); 

    UIBezierPath *clockHand = [[UIBezierPath alloc] init]; 
    [[UIColor yellowColor] setFill]; 
    [clockHand moveToPoint:CGPointMake(0, 20)]; 
    [clockHand addLineToPoint:CGPointMake(10, 0)]; 
    [clockHand addLineToPoint:CGPointMake(20, 20)]; 
    [clockHand fill]; 

    [clockHand removeAllPoints]; 
    [clockHand moveToPoint:CGPointMake(5, 100)]; 
    [clockHand addLineToPoint:CGPointMake(5, 20)]; 
    [clockHand addLineToPoint:CGPointMake(15, 20)]; 
    [clockHand addLineToPoint:CGPointMake(15, 100)]; 
    [clockHand closePath]; 
    [clockHand fill]; 


    UIImage *baseImage = UIGraphicsGetImageFromCurrentImageContext(); 
    NSLog(@"Image size is %@", NSStringFromCGSize(baseImage.size)); 
    UIGraphicsEndImageContext(); 

    //The screenshot will show baseimage, an arrow that is pointed upwards and at the top left of the screen 
    UIImageView *imageView = [[UIImageView alloc] initWithImage:baseImage]; 
    UIGraphicsEndImageContext(); 
    [self.view addSubview:imageView]; 

    //This code is just to see where 100, 100 is on screen 
    UIView *redView = [[UIView alloc] initWithFrame:CGRectMake(100,100, 5, 5)]; 
    redView.backgroundColor = [UIColor redColor]; 
    [self.view addSubview:redView]; 

    for (NSUInteger index = 0; index <= 8; index++) 
    { 
     //UIGraphicsBeginImageContextWithOptions(baseImage.size, NO, 0); //If I keep this line then nothing is shown 
     UIGraphicsBeginImageContextWithOptions(CGSizeMake(500, 600), NO, 0); // If I keep this line I can see some of teh rotations 
     CGContextRef con = UIGraphicsGetCurrentContext(); 
     CGContextTranslateCTM(con, 100, 100); //I want the clock hands to be centered around 100, 100 
     CGContextRotateCTM(con, 45*index*M_PI/180); 
     [baseImage drawAtPoint:CGPointMake(0, 0)]; 
     UIImageView *imageView = [[UIImageView alloc] initWithImage:UIGraphicsGetImageFromCurrentImageContext()]; 
     UIGraphicsEndImageContext(); 
     [self.view addSubview:imageView]; 
     imageView.opaque = YES; 
     imageView.backgroundColor = [UIColor clearColor]; 
     [self.view addSubview:imageView]; 
    } 
} 

Image showing what is coming on screen. If I use the <code>UIGraphicsBeginImageContextWithOptions(baseImage.size, NO, 0);</code> line instead of CGSizeMake(500,600) then all the rotated arrows don't show up

+0

«Я пытаюсь создать повернутые версии этого изображения» Как? В вашем коде нет вращения. – matt

+0

Многое зависит от того, что такое 'baseImage.size'. Что это? – matt

+0

@matt спасибо. BaseImage.size - 20 100. Хотелось запрограммировать простой, поэтому изначально только что показала ту часть, где я переводил начало в 100, 100, чтобы сделать центр часов. Я редактировал свой вопрос, чтобы показать код, который создает базовое изображение. Кроме того, добавлен снимок экрана, который показывает его (это стрелка, указывающая вверх в верхнем левом углу). –

ответ

1

Я вижу, что если я применяю CGContextTranslateCTM к изображению графического контекста, изображение не обращается

Конечно. Вы набираете 0,0. Но сначала вы применяете перевод CTM 100 100. Таким образом, вы на самом деле рисуете 100 100. Но контекст составляет всего лишь 20 пунктов. Таким образом, вы полностью выходите за пределы контекста. Нет контекста вне контекста, поэтому ничего не нарисовано.

+0

Можете помочь вам прочитать мою книгу, где я действительно решаю ту самую проблему, с которой вы работаете: http://www.apeth.com/iOSBook/ch15.html#_graphics_context_transforms – matt

+0

В любом случае, весь ваш подход ошибочен. Прочтите главу «Анимация» моей книги, где я покажу, как вращать часовую руку (фактически стрелку компаса), вращая CALayer. – matt

+0

спасибо. Вот что меня смущает. Я предположил, что когда я применяю преобразование к контексту, сам контекст сдвигается. I. Этот контекст имеет 20 точек, но начало координат составляет 100 100 после сдвига. Итак, все, что делается в rect (100, 100, 20, 100), должно быть в контексте. Разве это не так? Также, любите свою книгу по основам программирования iOS. Я все еще обволакиваю все материалы пользовательского интерфейса в большой книге (PS: Вы также должны написать книгу Obj-C вместе с книгой Swift еще несколько лет!) –

0

Основываясь на ответе @matt, я сделал несколько экспериментов. Запуск этого кода и комментарии о том, что ожидать, могут помочь другим новичкам понять, что происходит и как взаимодействуют рисование и перевод.

#define CROSS_SIZE 10 

-(void) conetxtTranslationDemos 
{ 
    UIGraphicsBeginImageContextWithOptions(CGSizeMake(CROSS_SIZE, CROSS_SIZE), NO, 0); 

    //Creates an image that looks like multiply symbol. Image is CROSS_SIZE by CROSS_SIZE wide 
    UIBezierPath *cross = [[UIBezierPath alloc] init]; 
    [[UIColor redColor] set]; 

    [cross moveToPoint:CGPointMake(0, CROSS_SIZE)]; 
    [cross addLineToPoint:CGPointMake(CROSS_SIZE, 0)]; 
    //[cross removeAllPoints]; 
    [cross moveToPoint:CGPointMake(0, 0)]; 
    [cross addLineToPoint:CGPointMake(CROSS_SIZE, CROSS_SIZE)]; 
    [cross stroke]; 


    UIImage *crossImage = UIGraphicsGetImageFromCurrentImageContext(); 
    UIGraphicsEndImageContext(); 
    NSLog(@"Image size is %@", NSStringFromCGSize(crossImage.size)); 

    //If you keep this you will see a cross image in top left of screen 
// UIImageView *imageView = [[UIImageView alloc] initWithImage:crossImage]; 
// [self.view addSubview:imageView]; 


    UIImageView *imageView; 
    UIGraphicsBeginImageContextWithOptions(CGSizeMake(100, 100), NO, 0); 

    CGContextRef con = UIGraphicsGetCurrentContext(); 
    //Results in all drawings being 40 points displaced downwards from top left of screen 
    CGContextTranslateCTM(con, 0, 40); 

    //Results in a multiply which has its top left at 20, 40 (40 due to above translation) 
    CGContextTranslateCTM(con, 20, 0); 
    [crossImage drawAtPoint:CGPointMake(0, 0)]; 
    imageView = [[UIImageView alloc] initWithImage:UIGraphicsGetImageFromCurrentImageContext()]; 
    [self.view addSubview:imageView]; 

    //Results in a multiply which has its top left at 0, 40 (40 due to original translation) 
    CGContextTranslateCTM(con, -20, 0); 
    [crossImage drawAtPoint:CGPointMake(0, 0)]; 
    imageView = [[UIImageView alloc] initWithImage:UIGraphicsGetImageFromCurrentImageContext()]; 
    [self.view addSubview:imageView]; 

    //Results in a multiply which has its top left at 40, 40+20/sqrt(2) (40 due to original translation) 
    CGContextTranslateCTM(con, 40, 20/sqrt(2)); 
    [crossImage drawAtPoint:CGPointMake(0, 0)]; 
    imageView = [[UIImageView alloc] initWithImage:UIGraphicsGetImageFromCurrentImageContext()]; 
    [self.view addSubview:imageView]; 

    //Undo above translation 
    CGContextTranslateCTM(con, -40, -20/sqrt(2)); 

    //Results in a add symbol instead of multiply. This is because a point at (10, 10) is now (10, 10) in rotated axis, which is 0, 2*10/sqrt(2) in normal axis. That is why you see you will bottom enplane of the add co-incide with top left of cross drawn above at (40, 40+20/sqrt(2)) 
    CGContextTranslateCTM(con, 40, 0); 
    CGContextRotateCTM(con, 45*M_PI/180); 
    [crossImage drawAtPoint:CGPointMake(0, 0)]; 
    imageView = [[UIImageView alloc] initWithImage:UIGraphicsGetImageFromCurrentImageContext()]; 
    [self.view addSubview:imageView]; 

} 

 Смежные вопросы

  • Нет связанных вопросов^_^