当前位置:  开发笔记 > 编程语言 > 正文

传递UIImage.CGImage时,CGContextDrawImage将图像上下颠倒

如何解决《传递UIImage.CGImage时,CGContextDrawImage将图像上下颠倒》经验,为你挑选了6个好方法。

有谁知道为什么CGContextDrawImage会把我的形象颠倒过来?我从我的应用程序加载图像:

UIImage *image = [UIImage imageNamed:@"testImage.png"];

然后简单地要求核心图形将其绘制到我的上下文中:

CGContextDrawImage(context, CGRectMake(0, 0, 145, 15), image.CGImage);

它呈现在正确的位置和尺寸,但图像是颠倒的.我一定错过了一些非常明显的东西吗?



1> Kendall Helm..:

代替

CGContextDrawImage(context, CGRectMake(0, 0, 145, 15), image.CGImage);

使用

[image drawInRect:CGRectMake(0, 0, 145, 15)];

在您的开始/结束CGcontext方法的中间.

这将以正确的方向将图像绘制到当前图像上下文中 - 我很确定这与UIImage保持方向知识有关,而CGContextDrawImage方法在不了解方向的情况下获取基础原始图像数据.

请注意,您将在许多方面遇到此问题,但一个具体示例是处理地址簿用户图像.


此解决方案不允许您在图像上使用CG函数,例如CGContextSetAlpha(),而第二个答案可以.
好的一点,虽然大多数情况下你不需要自定义alpha级别来绘制图像(通常那些需要alpha的事物会提前将图像烘焙到图像中).基本上我的座右铭是,尽可能使用一些代码,因为更多代码意味着更多的机会出现错误.
虽然它可能适用于Rusty,但[UIImage drawInRect:]存在的问题是它不是线程安全的.对于我的特定应用程序,这就是我首先使用CGContextDrawImage()的原因.

2> Cliff Viegas..:

即使应用了我提到的所有内容,我仍然会对图像进行戏剧化.最后,我刚刚使用Gimp创建了所有图像的"翻转垂直"版本.现在我不需要使用任何变换.希望这不会导致进一步的问题.

有谁知道为什么CGContextDrawImage会颠倒我的图像?我从我的应用程序加载图像:

Quartz2d使用不同的坐标系,原点位于左下角.因此,当Quartz绘制100*100图像的像素x [5],y [10]时,该像素将被绘制在左下角而不是左上角.从而导致'翻转'图像.

x坐标系统匹配,因此您需要翻转y坐标.

CGContextTranslateCTM(context, 0, image.size.height);

这意味着我们已经在x轴上将图像转换为0个单位,并在y轴上转换图像高度.然而,仅此一点就意味着我们的图像仍然是颠倒的,只是在我们希望绘制的地方下方绘制"image.size.height".

Quartz2D编程指南建议使用ScaleCTM并传递负值以翻转图像.您可以使用以下代码执行此操作 -

CGContextScaleCTM(context, 1.0, -1.0);

CGContextDrawImage通话之前将两者结合起来,您应该正确绘制图像.

UIImage *image = [UIImage imageNamed:@"testImage.png"];    
CGRect imageRect = CGRectMake(0, 0, image.size.width, image.size.height);       

CGContextTranslateCTM(context, 0, image.size.height);
CGContextScaleCTM(context, 1.0, -1.0);

CGContextDrawImage(context, imageRect, image.CGImage);

如果您的imageRect坐标与图像的坐标不匹配,请小心,因为您可能会得到意想不到的结果.

要转换回坐标:

CGContextScaleCTM(context, 1.0, -1.0);
CGContextTranslateCTM(context, 0, -imageRect.size.height);


为什么不使用`CGContextSaveGState()`和`CGContextRestoreGState()`来保存和恢复转换矩阵?
如果你正在使用drawLayer并想在上下文中绘制CGImageRef,这里的技术只是想要医生订购!如果有图像的rect,则CGContextTranslateCTM(context,0,image.size.height + image.origin.y),然后在CGContextDrawImage()之前将rect.origin.y设置为0.谢谢!

3> Rivera..:

两个世界中最好的,使用UIImage drawAtPoint:drawInRect:仍然指定您的自定义上下文:

UIGraphicsPushContext(context);
[image drawAtPoint:CGPointZero]; // UIImage will handle all especial cases!
UIGraphicsPopContext();

你也避免修改您的上下文CGContextTranslateCTMCGContextScaleCTM其中第二个答案呢.



4> kcmoffat..:

相关的Quartz2D文档:https://developer.apple.com/library/ios/documentation/2DDrawing/Conceptual/DrawingPrintingiOS/GraphicsDrawingOverview/GraphicsDrawingOverview.html#//apple_ref/doc/uid/TP40010156-CH14-SW4

翻转默认坐标系

在UIKit绘图中翻转会修改背景CALayer,以将具有LLO坐标系的绘图环境与UIKit的默认坐标系对齐.如果您只使用UIKit方法和绘图功能,则不需要翻转CTM.但是,如果将Core Graphics或Image I/O函数调用与UIKit调用混合使用,则可能需要翻转CTM.

具体来说,如果您通过直接调用Core Graphics函数绘制图像或PDF文档,则该对象将在视图的上下文中呈现为倒置.您必须翻转CTM才能正确显示图像和页面.

要将绘制到Core Graphics上下文的对象翻转以便在UIKit视图中显示时它正确显示,您必须分两步修改CTM.将原点转换为绘图区域的左上角,然后应用缩放平移,将y坐标修改为-1.执行此操作的代码类似于以下内容:

CGContextSaveGState(graphicsContext);
CGContextTranslateCTM(graphicsContext, 0.0, imageHeight);
CGContextScaleCTM(graphicsContext, 1.0, -1.0);
CGContextDrawImage(graphicsContext, image, CGRectMake(0, 0, imageWidth, imageHeight));
CGContextRestoreGState(graphicsContext);



5> ZpaceZombor..:

如果有人对在上下文中自定义rect中绘制图像的简单解决方案感兴趣:

 func drawImage(image: UIImage, inRect rect: CGRect, context: CGContext!) {

    //flip coords
    let ty: CGFloat = (rect.origin.y + rect.size.height)
    CGContextTranslateCTM(context, 0, ty)
    CGContextScaleCTM(context, 1.0, -1.0)

    //draw image
    let rect__y_zero = CGRect(origin: CGPoint(x: rect.origin.x, y:0), size: rect.size)
    CGContextDrawImage(context, rect__y_zero, image.CGImage)

    //flip back
    CGContextScaleCTM(context, 1.0, -1.0)
    CGContextTranslateCTM(context, 0, -ty)

}

将缩放图像以填充矩形.



6> mouviciel..:

我不确定UIImage,但这种行为通常发生在翻转坐标时.大多数OS X坐标系的原点都在左下角,如Postscript和PDF.但CGImage坐标系的起源位于左上角.

可能的解决方案可能涉及isFlipped属性或scaleYBy:-1仿射变换.

推荐阅读
U友50081205_653
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有