Почему CGImageCreateWithImageInRect принимает CGRect с точками, но затем использует пиксели?

Вот документация по CGImageCreateWithImageInRect.

Он принимает объект CGRect в качестве параметра. Из того, что я понимаю, CGRect находится в баллах

Однако в документации сказано:

"Ссылается на пиксели в полученном прямоугольнике, рассматривая первый пиксель внутри прямоугольника как источник подизображения".

Это казалось неточным и было доказано, когда мне нужно было изменить размер UIImages. Мне нужно было умножить размеры изображения на масштаб экрана, иначе мое изображение получилось неправильного размера

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

Если бы я не умножил масштаб, изображение получилось бы слишком маленьким.

Я прав, что это плохая документация (так как в ней не нужно брать CGRect, который находится в точках, а затем читать его как пиксели), или я не понимаю чего-то фундаментального здесь?

2 ответа

Из того, что я понимаю, CGRect находится в баллах

CGRect это "структура, которая содержит местоположение и размеры прямоугольника". Это основано на CGSize, Это определяется как "структура, которая содержит значения ширины и высоты". В этом, width определяется только как "значение ширины".

Нигде в документацииCGSize (или же CGRect) это говорит вам, как эти значения должны быть интерпретированы. Он никогда не говорит "это точки" или "это пиксели" или "это миллиметры". Это до звонящего. Документы для CGSize предупреждаю, что он может быть использован как вектор, а "размер" может быть отрицательным. Документы для CGRect предупреждаю, что происхождение может быть в разных местах. (CGRect используется как для UIKit, так и для Core Graphics, которые имеют разные системы координат.)

Я не думаю, что здесь что-то не так с документацией. CGRect ничего не обещает о масштабировании.

Тем не менее, вы не должны перечитывать использование таких слов, как "точка" и "пиксель", как это всегда означает "связанных с масштабом экрана", особенно в более старой документации. Слово "точка" часто просто означает "местоположение на изображении" в документах (и это то, что оно означает здесь). Эта конкретная функция восходит к OS X 10.4. В отсутствие CGContext"масштаб экрана" ничего не значит в любом случае. Эта функция работает с необработанными данными растрового изображения.

Я думаю, что документация является правильной (пиксели являются пикселями) на основе этого теста:

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 будет загружать любой актив, соответствующий масштабному коэффициенту системы. Другими словами, в этом сценарии вы не можете рассчитывать на то, что CGImage UIImage имеет согласованные размеры, и код масштабирования может пойти не так.

Другие вопросы по тегам