iPhone - неровные края при применении перспективы к CALayer
У меня есть CALayer, который я применяю перспективу для использования CGTransform3D
и указав m14
имущество. Когда перспектива применяется, слой имеет неровные края. Я слышал, что люди упоминают, что добавление прозрачной границы в 1 пиксель вокруг слоя поможет в этом. Я не знаю, как это сделать. Я пытался использовать border
а также borderWidth
свойства CALayer, но зубчатые края все еще там. Я также попытался уменьшить прямоугольник, который рисуется на 1 пиксель со всех сторон, но это тоже не помогает.
Любая помощь будет отличной! Спасибо!
5 ответов
Под "я слышал, как люди упоминают", я предполагаю, что вы имеете в виду обсуждение этого вопроса. Было предложено нарисовать контент в вашем CALayer так, чтобы он имел прозрачную границу в один пиксель за пределами основного контента, используя код
CGContextSetAllowsAntialiasing(theContext, true);
CGContextSetShouldAntialias(theContext, true);
в вашем Кварцевом рисунке для этого слоя.
Там также edgeAntialiasingMask
свойство на CALayer, но я не видел никакого влияния при использовании кода, подобного следующему:
layer.edgeAntialiasingMask = kCALayerLeftEdge | kCALayerRightEdge | kCALayerBottomEdge | kCALayerTopEdge;
на сглаживание преобразованных краев слоя. См. Также этот вопрос для обсуждения этого вопроса, а также о том, как они решили свою проблему, используя прозрачные рамки размером в один пиксель вокруг своих изображений.
Лучшее решение, которое я нашел для этой проблемы, состояло в том, чтобы установить shouldRasterize в YES и установить масштаб растеризации в соответствии с масштабом экрана устройства.
myLayer.shouldRasterize = YES;
myLayer.rasterizationScale = UIScreen.mainScreen().scale // iOS
myLayer.rasterizationScale = NSScreen.mainScreen()!.backingScaleFactor // OSX
Это в свою очередь сгладит края для вас.
Дайте вашему CALayer маску со вставкой 0.5 px от каждого края:
UIView *aliasedView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, width, height)];
CALayer *maskLayer = [[CALayer alloc] init];
maskLayer.frame = CGRectMake(0.5, 0.5, width-1, height-1);
maskLayer.backgroundColor = [UIColor whiteColor].CGColor;
aliasedView.layer.mask = maskLayer;
В Swift 3.0:
context.setAllowsAntialiasing(true)
context.setShouldAntialias(true)
Однопиксельная граница сглаживает края содержимого (!) Слоя:
- (UIImage *)drawAntiAliased:(UIImage *)image
{
const int B = 1; // Border width (anti-aliasing)
// Size of the output image
CGSize newImageSize = CGSizeMake(image.size.width + 2 * B, image.size.height + 2 * B);
UIGraphicsBeginImageContextWithOptions(newImageSize, NO, 0);
// Draw image with edge anti-aliasing
[image drawInRect:(CGRect){B, B, image.size}];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
Если вы хотите использовать свойства границ слоя, это больше не работает, потому что граница не является частью содержимого слоя и не подвержена сглаживанию.
настройка shouldRasterize
с другой стороны, влияет как содержание, так и границы.