Учитывая UIImage любого размера, я хочу сгенерировать квадратную «значку» размером в px
пикселей в сторону, без каких-либо искажений (растяжения). Тем не менее, я сталкиваюсь с небольшой хваткой. Не совсем уверен, где проблема. Вот что я делаю до сих пор.Правильное использование UIRectClip для масштабирования UIImage до размера значка
Во-первых, учитывая UImagesize
, я определить три вещи: 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}
Далее я создаю CGRectrect
, что является достаточно большим, чтобы быть обрезаны до нашего желаемого размера значка без искажений, плюс 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,5px шириной 50px с высоким прямоугольником для работы с ним и отсекающий прямоугольник, который захватывает «среднюю» часть 50x50.
На домашнем участке! Затем создадим наш контекст изображения, нарисуем UIImage (здесь myImage
здесь) в прямоугольник, зададим обрезающий прямоугольник, получим (предположительно теперь обрезанное) изображение, воспользуемся им и, наконец, очистим наш контекст изображения:
UIGraphicsBeginImageContext(rect.size);
[myImage drawInRect:rect];
UIRectClip(clipRect);
UIImage *icon = UIGraphicsGetImageFromCurrentImageContext();
// Do something with the icon here ...
UIGraphicsEndImageContext();
Только одна проблема: отсечения никогда не происходит! Я получаю изображение размером 63px в ширину x 50px. :(
Возможно, я неправильно использую/не понимаю UIRectClip? Я пытался перетасовать различные вещи: обмен rect
и clipRect
, перемещение UIRectClip до drawInRect:. Нет кубиков.
Я попытался найти пример этого метода онлайн, но безрезультатно. Для записи, UIRectClip определяется как:
Изменяет текущий путь отсечения по , пересекающая его с указанным прямоугольника.
шаркая вещи вокруг заставляет нас немного ближе:
UIGraphicsBeginImageContext(clipRect.size);
UIRectClip(rect);
[myImage drawInRect:rect];
Теперь у нас нет искажений, но обрезается изображение не по центру оригинала, как я ожидал.Тем не менее, по крайней мере, изображение равно 50x50, хотя имена переменных теперь загрязнены в результате упомянутого перетасовки. (Я с уважением оставлю переименование в качестве упражнения для читателя.)
Спасибо за разделение этого! Прошло некоторое время с тех пор, как я посмотрел, что у меня получилось. Я определенно не хотел или не искал никаких искажений, используя мой метод. Ваш «самый большой возможный квадрат» звучит разумно, и я очень рад слышать, что UIRectClip не нужен. (Другие читатели, пожалуйста, взвесьте и посмотрите, как это вам тоже!) –
Благодарим вас, в частности, за предложение «Также не обязательно использовать UIClipRect - если вы сделаете контекст размером с изображением, которое хотите извлечь, никакой фактический рисунок не будет сделан вне этого rect так или иначе " – xaphod