【问题标题】:renderInContext image drawing with specified size具有指定大小的 renderInContext 图像绘制
【发布时间】:2013-07-31 09:11:45
【问题描述】:

如何在不使用 CGAffineTransform 的情况下绘制小于上下文大小的图像?

UIGraphicsBeginImageContext(size);
CGContextRef context = UIGraphicsGetCurrentContext();
// center image
CGContextTranslateCTM(context, placement.origin.x, placement.origin.y);
[imageView.layer renderInContext:context];

问题在于,如果imageView.image.size 大于size,它将居中绘制,但在边界处剪切(图像大于绘图区域)。我希望图像适合,所以想减小imageView.image.size 的大小。有没有办法使用renderInContext 来实现这一点?

【问题讨论】:

    标签: ios cocoa-touch core-graphics cgcontext


    【解决方案1】:

    通过[imageView.layer renderInContext:context];,您无法更改大小(或者我没有找到方法)。这样做的唯一选择是现在使用 drawImage 创建图像(根据请求的大小),分配新的 UIImageView 并绘制其图层。

    UIImage *resizedImage = [self createNewImageFrom:currentImage withSize:size];
    UIImageView *imageView = [[UIImageView alloc] initWithImage:resizedImage];
    // ...
    [imageView.layer renderInContext:context];
    
    
    - (UIImage*)createNewImageFrom:(UIImage*)image withSize:(CGSize)size {
        UIGraphicsBeginImageContextWithOptions(size, NO, 0.0);
        CGContextRef context = UIGraphicsGetCurrentContext();
        CGContextTranslateCTM(context, 0.0f, size.height);
        CGContextScaleCTM(context, 1.0, -1.0);
        CGContextDrawImage(context, CGRectMake(0.0f, 0.0f, size.width, size.height), image.CGImage);
        UIImage *outputImage = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
        return outputImage;
    }
    

    【讨论】:

    • 对否决票有什么意见,或者只是到处乱说?如果我做错了什么,最好告知是什么。
    • 我正在寻找一些方法将图层渲染为不同的大小,最后我找到了方法,您的回答可能会误导其他与我相似的人。
    【解决方案2】:

    为什么要在不改变上下文的情况下这样做?这是完成这项工作的最佳工具!

    这里最简单的方法是调用CGContextScaleCTM 将比例因子应用于上下文。该比例因子将影响到上下文的所有绘图,包括对-renderIntoContext: 的调用。

    【讨论】:

    • 因为上下文已经被转换,我需要它保持原样 - 使用 saveCGState n Restore 也会产生问题。无论如何,我已经找到了解决我的问题的方法并在这里进行了描述,明天会接受这个答案(不能更早)。
    • 如果 CGContextSaveGState/CGContextRestoreGState 没有恢复上下文的 CTM,那么你做错了什么。您的方法至少使用两倍的内存,并且执行时间至少是转换上下文的两倍。就像我说的:转换上下文是准确适合这项工作的工具。
    【解决方案3】:

    这是缩放尺寸的版本,只需将 scale 替换为 size.width 和 size.height 即可获得任何目标尺寸。

    对于 UIView:

    -(UIImage*)convertViewToImage:(UIView*)v withScale:(float)scale{
        //create bitmap context with scaled size
        CGSize s = v.bounds.size;
        s.width *= scale;
        s.height *= scale;
        UIGraphicsBeginImageContextWithOptions(s, NO, [UIScreen mainScreen].scale);
    
        //scale CTM to render and resotre CTM
        CGContextRef context = UIGraphicsGetCurrentContext();
        CGContextSaveGState(context);
        CGContextScaleCTM(context, scale, scale);
        [v.layer renderInContext: context];
        CGContextRestoreGState(context);
    
        UIImage*image = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
        return image;
    }
    

    对于 UIScrollView

    -(UIImage*)convertScrollContentToImage:(UIScrollView*)sv withScale:(float)scale{
        //create bitmap context with scaled size
        CGSize s = sv.contentSize;
        s.width *= scale;
        s.height *= scale;
        UIGraphicsBeginImageContextWithOptions(s, NO, [UIScreen mainScreen].scale);
    
    
        {
            //set scroll.frame.size to contentSize, and contentOffset to 0
            CGPoint savedContentOffset = sv.contentOffset;
            CGRect savedFrame = sv.frame;
    
            sv.contentOffset = CGPointZero;
            sv.frame = CGRectMake(0, 0, sv.contentSize.width, sv.contentSize.height);
    
            //scale CTM to render and resotre CTM
            CGContextRef context = UIGraphicsGetCurrentContext();
            CGContextSaveGState(context);
            CGContextScaleCTM(context, scale, scale);
            [sv.layer renderInContext: context];
            CGContextRestoreGState(context);
    
            //set scroll.frame.size and ContentOffset back
            sv.contentOffset = savedContentOffset;
            sv.frame = savedFrame;
    
        }
    
        UIImage*image = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
        return image;
    }
    

    【讨论】:

    • CGContextSaveGState 非常消耗内存。我看不出这段代码比我的有任何优势,你能提供任何评论吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-05-30
    • 2013-06-06
    • 1970-01-01
    • 1970-01-01
    • 2016-03-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多