Правильное использование UIRectClip для масштабирования UIImage до размера иконки
УчитываяUIImage любого размера, я хочу сгенерировать квадратную версию в виде иконки,px
пикселей в сторону, без каких-либо искажений (растяжения). Тем не менее, я сталкиваюсь с небольшой загадкой. Не совсем уверен, где проблема. Вот что я делаю до сих пор.
Во-первых, учитываяUImage size
Я определяю три вещи:ratio
использовать при уменьшении изображения;delta
(разница между желаемым размером иконки и самой длинной стороной) иoffset
(который используется для определения нашей исходной координаты при вырезании изображения):
if (size.width > size.height) {
ratio = px / size.width;
delta = (ratio*size.width - ratio*size.height);
offset = CGPointMake(delta/2, 0);
} else {
ratio = px / size.height;
delta = (ratio*size.height - ratio*size.width);
offset = CGPointMake(0, delta/2);
}
Теперь предположим, что у вас есть изображение шириной 640px и высотой 480px, и мы хотим получить из этого значок 50px x 50px. Ширина больше высоты, поэтому наши расчеты таковы:
ratio = 50px / 640px = 0.078125
delta = (ratio * 640px) - (ratio * 480px) = 50px - 37.5px = 12.5px
offset = {x=6.25, y=0}
Далее я создаюCGRect rect
это достаточно большой, чтобы обрезать до желаемого размера значка без искажений, а такжеclipRect
для отсечения:
CGRect rect = CGRectMake(0.0, 0.0, (ratio * size.width) + delta,
(ratio * size.height) + delta);
CGRect clipRect = CGRectMake(offset.x, offset.y, px, px);
Подставляя наши значения сверху, получаем:
rect = origin {x=0.0, y=0.0}, size {width=62.5, height=50.0}
clipRect = origin {x=6.25, y=0}, size {width=50.0, height=50.0}
Итак, теперь у нас есть прямоугольник шириной 62,5 х 50 х и для работы с ним, а также прямоугольник отсечения, который захватывает «среднюю» часть 50х50.
На домашнем участке! Затем мы настраиваем наш контекст изображения, рисуемUIImage (называетсяmyImage
здесь) в прямоугольник, установите прямоугольник отсечения, получите (предположительно теперь обрезанное) изображение, используйте его и, наконец, очистите наш контекст изображения:
UIGraphicsBeginImageContext(rect.size);
[myImage drawInRect:rect];
UIRectClip(clipRect);
UIImage *icon = UIGraphicsGetImageFromCurrentImageContext();
// Do something with the icon here ...
UIGraphicsEndImageContext();
Только одна проблема: отсечение никогда не происходит! Я получаю изображение шириной 63px и высотой 50px.:(
Возможно, я неправильно использую / недопониманиеUIRectClip? Я пытался перетасовать разные вещи вокруг: обменять использованиеrect
а такжеclipRect
движетсяUIRectClip доdrawInRect:, Нет кости.
Я попытался найти пример этого метода в Интернете, но безрезультатно. Для записи,UIRectClip определяется как:
Изменяет текущий путь отсечения, пересекая его с указанным прямоугольником.
Перемешивание вещей вокруг нас приближает нас немного:
UIGraphicsBeginImageContext(clipRect.size);
UIRectClip(rect);
[myImage drawInRect:rect];
Теперь у нас нет искажений, но вырезанное изображение не отцентрировано на оригинале, как я ожидал. Тем не менее, по крайней мере, изображение имеет размер 50x50, хотя имена переменных теперь загрязняются в результате этой перестановки. (Я почтительно оставлю переименование в качестве упражнения для читателя.)