iOS: сбой сглаживания (PNG в CALayer)

Я пытаюсь нарисовать это изображение на экране:

src_image

Это код:

        CALayer* dullLayer = [CALayer layer];
        {                
            dullLayer.frame = CGRectMake(0,0,BUTTON_SIZE,BUTTON_SIZE);

            dullLayer.position = CGPointFromPoint2D( btnCenter );

            dullLayer.opacity = topQuadrant ? 1.0 : 0.5;


            [wheelLayer addSublayer: dullLayer];
        }


        UIImage* test = [UIImage imageNamed: @"OuterButton_Dull.png"];

        dullLayer.contents = (id) [test CGImage];

Вот что я получаю:

render_fail

Что дает? Почему края такие неровные? Сравните это с изображениями римских цифр, которые были созданы для экрана точно таким же образом.

я пытался

            dullLayer.edgeAntialiasingMask = 0x0f; // binary 1111

но безрезультатно.

РЕДАКТИРОВАТЬ: http://lists.apple.com/archives/cocoa-dev/2008/Feb/msg02070.html


person P i    schedule 14.08.2011    source источник


Ответы (3)


Если итоговое изображение, которое вы опубликовали, имеет тот же размер, что и на экране, то вы просто используете слишком большое изображение. Изображение PNG не является векторным изображением, поэтому его уменьшение всегда приводит к некоторому наложению; чем дальше вы масштабируете, тем хуже становится. В таких случаях сглаживание будет иметь ограниченный эффект.

Тот факт, что вы не видите его для числовых изображений, частично объясняется тем, что оно не содержит тонких высококонтрастных линий, как на другом изображении, и частично, возможно, тем, что вы используете для них изображения меньшего размера.

Если у вас есть исходное изображение в виде векторного изображения, попробуйте уменьшить его до нужного размера перед преобразованием в PNG. Если вам нужна версия с более высоким разрешением где-то еще в вашем приложении, рассмотрите возможность создания нескольких файлов PNG, каждый с разным разрешением.

Если у вас нет исходного изображения в виде векторного изображения, попробуйте найти замену. В Интернете есть несколько хороших источников бесплатных графических файлов, таких как http://www.openclipart.org/ или http://www.clker.com/.

person Desmond    schedule 14.08.2011
comment
БЛАГОДАРНОСТЬ! Именно это и происходило. Я опубликую полный ответ ниже. - person P i; 14.08.2011
comment
PS Да, цифры были гораздо меньше изображений - person P i; 14.08.2011

Я только что сделал сообщение об этом: http://kellenstyler.com/?p=1360

Есть несколько вещей, которые вы можете сделать, если добавите изображения с помощью кода, а также несколько трюков, которые позволят вам немного почистить его.

Посмотрите, поможет ли что-нибудь в следующем коде:

UIImage * img =[UIImage imageWithData:[NSData dataWithContentsOfFile:[[[NSBundle mainBundle ] resourcePath ] stringByAppendingPathComponent:@"AliasImage.png" ] ] ];
CGRect imageRect = CGRectMake( 0 , 0 , img.size.width + 4 , img.size.height + 4 );
UIGraphicsBeginImageContext( imageRect.size );
[img drawInRect:CGRectMake( imageRect.origin.x + 2 , imageRect.origin.y + 2 , imageRect.size.width - 4 , imageRect.size.height - 4 ) ];
CGContextSetInterpolationQuality( UIGraphicsGetCurrentContext() , kCGInterpolationHigh );
img = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
[aliasImage setImage:img ];

aliasImage.transform = CGAffineTransformScale(aliasImage.transform , 0.45 , 0.45 );
aliasImage.layer.shouldRasterize = YES;
aliasImage.layer.rasterizationScale = 0.45;
aliasImage.layer.edgeAntialiasingMask = kCALayerLeftEdge | kCALayerRightEdge | kCALayerBottomEdge | kCALayerTopEdge;
aliasImage.clipsToBounds = NO;
aliasImage.layer.masksToBounds = NO;
person Designerd    schedule 10.09.2011

Десмонд справился.

Похоже, сглаживание в фреймворках Apple работает только на соседних пикселях. поэтому, если вы уменьшите изображение в 4 раза, пиксель 0,0 будет усреднен по сравнению с пикселем 2,0, т.е. пиксель 1,0 будет полностью отброшен. так что если у вас острые края, это не взломает его.

Решение состоит в многократном уменьшении изображения на 50%, пока оно не станет в ‹ 2 раза больше желаемого размера.

Вот что произойдет, если я постепенно уменьшаю исходное изображение 600 x 600, каждый раз уменьшая его вдвое и отображая результат в CALayer 256 x 256:

progressive_reduction

Третье изображение фактически уменьшено до целевого размера. Как ни странно, дальнейшее уменьшение (которое автоматически увеличивается до 75 -> 256 для отображения) на самом деле выглядит лучше всего.

Так что на самом деле в этом случае решение состояло в том, чтобы уменьшить его до тех пор, пока он не станет меньше желаемого размера, а затем позволить графической структуре Apple расширить его по мере необходимости.

person P i    schedule 14.08.2011