У меня есть UIImageView (полный кадр и прямоугольник), который я вращаю с помощью CGAffineTransform. UIImage UIImageView заполняет весь кадр. Когда изображение поворачивается и рисуется, края кажутся заметно зазубренными. Есть ли что-нибудь, что я могу сделать, чтобы выглядеть лучше? Это явно не сглаживается с фоном.
Любые быстрые и грязные методы сглаживания для повернутого UIImageView?
Ответ 1
Не забудьте установить соответствующие параметры сглаживания:
CGContextSetAllowsAntialiasing(theContext, true);
CGContextSetShouldAntialias(theContext, true);
Ответ 2
Края слоев CoreAnimation по умолчанию не сглаживаются по iOS. Однако есть ключ, который вы можете установить в Info.plist, который позволяет сглаживать края: UIViewEdgeAntialiasing.
Если вы не хотите накладных расходов на производительность для включения этой опции, обход - добавить прозрачную границу 1px по краю изображения. Это означает, что "ребра" изображения больше не находятся на краю, поэтому не нуждаются в специальной обработке!
Ответ 3
Новый API - iOS 6/7
Также работает для iOS 6, как отметил @Chris, но не был опубликован до iOS 7.
Начиная с iOS 7, у CALayer есть новое свойство allowsEdgeAntialiasing
, которое делает именно то, что вы хотите в этом случае, без каких-либо накладных расходов, чтобы включить его для всех просмотров в вашем приложении! Это свойство CALayer, поэтому для включения UIView вы используете myView.layer.allowsEdgeAntialiasing = YES
.
Ответ 4
просто добавьте прозрачную рамку 1px к вашему изображению
CGRect imageRect = CGRectMake(0, 0, image.size.width, image.size.height);
UIGraphicsBeginImageContextWithOptions(imageRect.size, NO, 0.0);
[image drawInRect:CGRectMake(1,1,image.size.width-2,image.size.height-2)];
image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
Ответ 5
просто добавьте "Renders with edge antialiasing" с YES в plist, и он будет работать.
Ответ 6
Я бы полностью рекомендовал следующую библиотеку.
http://vocaro.com/trevor/blog/2009/10/12/resize-a-uiimage-the-right-way/
Он содержит множество полезных расширений для UIImage, которые решают эту проблему, а также включают код для создания эскизов и т.д.
Наслаждайтесь!
Ответ 7
Лучший способ найти гладкие края и резкое изображение - сделать это:
CGRect imageRect = CGRectMake(0, 0, self.photo.image.size.width, self.photo.image.size.height);
UIGraphicsBeginImageContextWithOptions(imageRect.size, NO, 0.0);
[self.photo.image drawInRect:CGRectMake(1, 1, self.photo.image.size.width - 2, self.photo.image.size.height - 2)];
self.photo.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
Добавление ключа Info.plist, как описано в некоторых случаях, сильно влияет на производительность, и если вы используете это, вы в основном применяете его ко всему, а не только к одному месту, в котором оно вам нужно.
Кроме того, не просто используйте UIGraphicsBeginImageContext(imageRect.size);
, иначе слой будет размытым. Вы должны использовать UIGraphicsBeginImageContextWithOptions
, как я показал.
Ответ 8
Я нашел это решение от здесь, и это идеально:
+ (UIImage *)renderImageFromView:(UIView *)view withRect:(CGRect)frame transparentInsets:(UIEdgeInsets)insets {
CGSize imageSizeWithBorder = CGSizeMake(frame.size.width + insets.left + insets.right, frame.size.height + insets.top + insets.bottom);
// Create a new context of the desired size to render the image
UIGraphicsBeginImageContextWithOptions(imageSizeWithBorder, NO, 0);
CGContextRef context = UIGraphicsGetCurrentContext();
// Clip the context to the portion of the view we will draw
CGContextClipToRect(context, (CGRect){{insets.left, insets.top}, frame.size});
// Translate it, to the desired position
CGContextTranslateCTM(context, -frame.origin.x + insets.left, -frame.origin.y + insets.top);
// Render the view as image
[view.layer renderInContext:UIGraphicsGetCurrentContext()];
// Fetch the image
UIImage *renderedImage = UIGraphicsGetImageFromCurrentImageContext();
// Cleanup
UIGraphicsEndImageContext();
return renderedImage;
}
использование:
UIImage *image = [UIImage renderImageFromView:view withRect:view.bounds transparentInsets:UIEdgeInsetsZero];