【问题标题】:Why does CGImageCreateWithImageInRect take a CGRect with points but then use pixels?为什么 CGImageCreateWithImageInRect 采用点的 CGRect 但然后使用像素?
【发布时间】:2015-02-12 04:18:06
【问题描述】:

这是CGImageCreateWithImageInRect 上的文档。

它接受一个 CGRect 对象作为参数。据我了解,CGRect 在 points

但是文档说:

"引用生成的矩形内的像素,将 矩形内的第一个像素作为子图像的原点。"

这似乎不准确,并且在我需要调整 UIImage 大小时得到证明。我需要将图像尺寸乘以屏幕比例,否则我的图像尺寸错误

var imageRef:CGImageRef = CGImageCreateWithImageInRect(image.CGImage, CGRectMake(0, 0, image.size.width*UIScreen.mainScreen().scale, image.size.height*UIScreen.mainScreen().scale))

如果我不按比例相乘,图像就会变得太小。

我是对的,这是一个糟糕的文档(因为它不应该采用以点为单位的 CGRect,然后将其读取为像素)还是我不理解这里的基本内容?

【问题讨论】:

  • 当任何东西说像素时,你应该把它解释为点(像素*比例)
  • 换一种说法“像素”==“虚拟像素”
  • 是的,一个点是像素*比例。问题是它以点为参数,然后将它们读取为像素!
  • CGRect、CGPoint、CGSize等,都是点。 CoreGraphics 和/up 中的所有测量值始终以点为单位。唯一以像素为单位的时间是在构建 CGBitmapContext 时。
  • 正如大卫所说,Core Graphics 基本结构和功能不了解逻辑点,仅适用于物理点

标签: ios swift ios8 appledoc


【解决方案1】:

我认为基于此测试的文档是正确的(像素就是像素):

var filename = "InterfaceButtons_Scores@2x.png"
var path = NSBundle.mainBundle().pathForResource(filename,ofType:nil)
var dataProvider = CGDataProviderCreateWithFilename(path!)
var cgimg = CGImageCreateWithPNGDataProvider(dataProvider, nil, false, .RenderingIntentDefault)!

print("size of 100x100px file loaded into CGImage")
print(CGImageGetHeight(cgimg));
print(CGImageGetWidth(cgimg));

var croppedImg = CGImageCreateWithImageInRect(cgimg, CGRect(x: 0, y: 0, width: 100, height: 100))

print("size of CGImage created with 100x100 Rect from 100x100 image")
print(CGImageGetHeight(croppedImg));
print(CGImageGetWidth(croppedImg));


filename = "InterfaceButtons_Scores@1x.png"
path = NSBundle.mainBundle().pathForResource(filename,ofType:nil)
dataProvider = CGDataProviderCreateWithFilename(path!)
cgimg = CGImageCreateWithPNGDataProvider(dataProvider, nil, false, .RenderingIntentDefault)!

print("size of 51x51px file loaded into CGImage")
print(CGImageGetHeight(cgimg));
print(CGImageGetWidth(cgimg));

croppedImg = CGImageCreateWithImageInRect(cgimg, CGRect(x: 0, y: 0, width: 100, height: 100))

print("size of CGImage created with 100x100 Rect from 51x51 image")
print(CGImageGetHeight(croppedImg));
print(CGImageGetWidth(croppedImg));

输出:

size of 100x100px file loaded into CGImage
100
100
size of CGImage created with 100x100 Rect from 100x100 image
100
100
size of 51x51px file loaded into CGImage
51
51
size of CGImage created with 100x100 Rect from 51x51 image
51
51

如果不知道您是如何尝试调整它们的大小以及您看到的确切结果,我不确定要对您的 UIImage 调整大小说些什么。我确实知道,如果您从资产目录中的资产创建 UIImage(使用 UIImage(named:)),那么 CGImage 属性的实际像素尺寸将取决于设备或模拟器的比例因子。如果同一资源有多个尺寸,UIImage 将加载与系统比例因子匹配的资源。换句话说,在这种情况下,你不能指望 UIImage 的 CGImage 具有一致的尺寸,缩放代码可能会出错。

【讨论】:

    【解决方案2】:

    据我了解,CGRect 是以点为单位的

    CGRect 是“包含矩形位置和尺寸的结构”。它基于CGSize。这被定义为“包含宽度和高度值的结构”。其中,width 仅定义为“宽度值”。

    documentation of CGSize(或CGRect)中没有任何地方告诉您如何解释这些值。它从不说“这些是点”或“这些是像素”或“这些是毫米”。这取决于调用者。 CGSize 的文档警告您它可能被用作向量并且“大小”可能是负数。 CGRect 的文档警告您来源可能在不同的地方。 (CGRect 用于 UIKit 和 Core Graphics,它们有不同的坐标系。)

    我认为这里的文档没有任何问题。 CGRect 不承诺任何关于扩展的内容。

    也就是说,您不应过度解读“点”和“像素”等词的使用,因为它们始终表示“与屏幕比例有关”,尤其是在旧文档中。 “点”一词在文档中通常仅表示“图像中的位置”(这就是它的意思)。这个特殊的功能可以追溯到 OS X 10.4。在没有CGContext 的情况下,“屏幕比例”无论如何都没有多大意义。此函数适用于原始图像位图数据。

    【讨论】:

      猜你喜欢
      • 2012-02-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-15
      • 2013-06-20
      相关资源
      最近更新 更多