У меня есть некоторый код, который изменяет размеры изображения, чтобы я мог получить масштабированный фрагмент центра изображения - я использую это, чтобы взять UIImage
и вернуть маленькое квадратное представление изображения, аналогично тому, что видно в представлении альбома приложение Фотографии. (Я знаю, что мог бы использовать UIImageView
и настроить режим кадрирования для достижения тех же результатов, но эти изображения иногда отображаются в UIWebViews
).
Я начал замечать некоторые сбои в этом коде, и я немного озадачен. У меня есть две разные теории, и мне интересно, есть ли одна из них на основе.
Теория 1) Я достигаю обрезки, рисуя в контексте закадрового изображения моего целевого размера. Поскольку мне нужна центральная часть изображения, я устанавливаю CGRect
аргумент, передаваемый drawInRect
для чего-то большего, чем границы моего контекста изображения. Я надеялся, что это было кошерно, но вместо этого я пытаюсь нарисовать другое воспоминание, которого я не должен касаться?
Теория 2) Я делаю все это в фоновом потоке. Я знаю, что есть части UIKit, которые ограничены основным потоком. Я предполагал / надеялся, что рисование за пределами экрана не было одним из них. Я ошибся?
(О, как я скучаю по NSImage's drawInRect:fromRect:operation:fraction:
методу.)
Ответы:
Обновление 2014-05-28: я написал это, когда iOS 3 или около того была новинкой, я уверен, что к настоящему времени есть лучшие способы сделать это, возможно, встроенные. Как уже упоминали многие, этот метод не учитывает ротацию; Прочитайте некоторые дополнительные ответы и распространите любовь, чтобы ответы на этот вопрос были полезны для всех.
Оригинальный ответ:
Я собираюсь скопировать / вставить свой ответ на тот же вопрос в другом месте:
Для этого не существует простого метода класса, но есть функция, которую вы можете использовать для получения желаемых результатов:
CGImageCreateWithImageInRect(CGImageRef, CGRect)
она поможет вам.Вот краткий пример его использования:
источник
imageOrientation
установлено значение, отличное от «вверх»,CGImage
оно поворачивается относительноUIImage
и прямоугольник обрезки будет неправильным. Вы можете вращать прямоугольник обрезки соответствующим образом, но у вновь созданногоUIImage
будетimageOrientation
вверх, так что обрезанныйCGImage
будет вращаться внутри него.[UIImage imageWithCGImage:imageRef scale:largeImage.scale orientation:largeImage.imageOrientation];
Чтобы обрезать изображения сетчатки, сохраняя тот же масштаб и ориентацию, используйте следующий метод в категории UIImage (iOS 4.0 и выше):
источник
self.scale
, нет?CGImageRelease(imageRef);
с включенной ARC?Вы можете создать категорию UIImage и использовать ее там, где вам нужно. Основано на ответах HitScans и комментариях ниже.
Вы можете использовать это так:
источник
[[UIScreen mainScreen] scale]
простоself.scale
? Масштаб изображения может не совпадать с масштабом экрана.No visible @interface for 'UIImage' declares the selector 'crop'
хотя я поместил файлы категорий .h и .m в свой проект и импортировал .h в класс, который я использую категории. Любая идея?Версия Swift 3
с помощью этой функции моста
CGRectMake
->CGRect
(кредиты на этот ответ ответили@rob mayoff
):Использование:
Вывод:
источник
guard
первой строки, еслиUIImage.CGImage
возвращаетсяnil
и зачем использовать,var
когдаlet
работает отлично.cropping(to:)
внимательно прочитайте документы . РезультирующаяCGImage
содержит сильную ссылку на большее,CGImage
из которого он был обрезан. Так что, если вы хотите только удерживать обрезанное изображение и не нуждаетесь в оригинале, взгляните на другие решения.right
то cgImage должен быть повернут на 90 градусов по часовой стрелке, следовательно, прямоугольник кадрирования тоже должен вращатьсяВот моя реализация обрезки UIImage, которая подчиняется свойству imageOrientation. Все ориентации были тщательно проверены.
источник
implicit declaration of function 'rad' is invalid in c99
можно удалить, заменив: rad (90), rad (-90), rad (-180) -> M_PI_2, -M_PI_2, -_M_PIcontains undefined reference for architecture armv7
Я скучаю по библиотеке? CoreGraphics импортируется.Heads up: все эти ответы предполагают
CGImage
объект изображения с обратной стороной.image.CGImage
может вернуть ноль, еслиUIImage
он поддерживается aCIImage
, что было бы в случае, если вы создали это изображение с помощьюCIFilter
.В этом случае вам, возможно, придется нарисовать изображение в новом контексте и вернуть это изображение ( медленно ).
источник
Ни один из ответов здесь не обрабатывает все проблемы масштаба и вращения на 100% правильно. Вот обобщение всего, что было сказано до сих пор, начиная с iOS7 / 8. Он предназначен для включения в качестве метода в категорию на UIImage.
источник
Быстрая версия
awolf
ответа, которая сработала для меня:источник
Большинство ответов, которые я видел, касается только позиции (0, 0) для (x, y). Хорошо, это один случай, но я бы хотел, чтобы моя операция кадрирования была сосредоточена. Мне потребовалось некоторое время, чтобы понять, какая строка следует за комментарием WTF.
Давайте возьмем случай изображения, снятого с портретной ориентацией:
Надеюсь, это имеет смысл! Если этого не произойдет, попробуйте другие значения, и вы увидите, что логика инвертируется, когда дело доходит до выбора правильных x, y, width и height для вашего cropRect.
источник
swift3
источник
Быстрое расширение
источник
Лучшее решение для обрезки UIImage в Swift , с точки зрения точности, масштабирования пикселей ...:
Инструкции, используемые для вызова этой функции:
Примечание: исходное вдохновение исходного кода, написанное в Objective-C, было найдено в блоге "Cocoanetics".
источник
Ниже может помочь фрагмент кода.
источник
Выглядит немного странно, но прекрасно работает и учитывает ориентацию изображения:
источник
Свифт 5:
источник
источник
источник
На iOS9.2SDK я использую метод ниже, чтобы преобразовать кадр из UIView в UIImage
источник
Обновление Swift 2.0 (
CIImage
совместимость)Расширение от ответа Максима, но работает, если ваше изображение также
CIImage
основано.источник
Вот обновленная версия Swift 3, основанная на ответе Лапши
источник
Следуй за ответом @Arne. Я просто фиксирую функцию категории. положить его в категорию UIImage.
источник
Я не был удовлетворен другими решениями, потому что они либо рисуют несколько раз (используя больше энергии, чем необходимо), либо имеют проблемы с ориентацией. Вот что я использовал для масштабированного квадратного обрезанного изображения из изображения UIImage *.
источник
Я использую метод ниже.
}
источник
Посмотрите на https://github.com/vvbogdan/BVCropPhoto
источник