如何在翻译图像图形上下文后使用drawAtPoint绘制UIImage

时间:2016-11-22 03:33:59

标签: ios uiimageview uiimage uikit

我有一个时钟指针的图像。我正在尝试创建此图像的旋转版本,以便Ic使用动画播放它(使用UIImageView's animatedImages方法)。

在下面的代码中,我看到如果我将CGContextTranslateCTM应用于图像图形上下文,则不会绘制图像,除非我增加UIGraphicsBeginImageContextWithOptions的大小以使其大于图像大小。

为什么需要这个?我认为所有的翻译都是为了移动drawAtPoint:如何解释0,0在哪里的定义?

**编辑代码显示更多细节*

-(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

2 个答案:

答案 0 :(得分:1)

  

我看到如果我将CGContextTranslateCTM应用于图像图形上下文,则不会绘制图像

当然。你画的是0,0。但首先你应用的翻译CTM为100,100。所以你实际上是100,100。但背景只有20个点。所以你完全在上下文之外画画。在上下文之外没有上下文,因此没有任何内容。

答案 1 :(得分: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];

}