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 с другой стороны, влияет как содержание, так и границы.

Другие вопросы по тегам