Какао Touch - добавление текстуры с наложением вида

У меня есть набор плиток в виде UIViews, у которых есть программируемый цвет фона, и каждый может быть разного цвета. Я хочу добавить текстуру, например фаску с боковым освещением, каждому из них. Можно ли это сделать с помощью наложения или каким-либо другим способом?

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


person Jim    schedule 10.11.2011    source источник


Ответы (3)


Это может кому-то помочь, хотя это было собрано из других тем на SO. Чтобы создать скошенное изображение плитки с произвольным цветом для обычного и для отображения сетчатки, я сделал скошенное изображение в фотошопе и установил насыщенность равной нулю, создав изображение в оттенках серого под названием tileBevel.png

tileBevel.png

Еще я создал один для дисплея сетчатки ([email protected])

Вот код:

+ (UIImage*) createTileWithColor:(UIColor*)tileColor {

    int pixelsHigh = 44;
    int pixelsWide = 46;
    UIImage *bottomImage;

    if([UIScreen respondsToSelector:@selector(scale)] && [[UIScreen mainScreen] scale] == 2.0) {
        pixelsHigh *= 2;
        pixelsWide *= 2;
        bottomImage = [UIImage imageNamed:@"[email protected]"];        
    }
    else {
        bottomImage = [UIImage imageNamed:@"tileBevel.png"];
    }

    CGImageRef theCGImage = NULL;
    CGContextRef tileBitmapContext = NULL;

    CGRect rectangle = CGRectMake(0,0,pixelsWide,pixelsHigh);

    UIGraphicsBeginImageContext(rectangle.size);

    [bottomImage drawInRect:rectangle];

    tileBitmapContext = UIGraphicsGetCurrentContext();

    CGContextSetBlendMode(tileBitmapContext, kCGBlendModeOverlay);

    CGContextSetFillColorWithColor(tileBitmapContext, tileColor.CGColor);        
    CGContextFillRect(tileBitmapContext, rectangle);

    theCGImage=CGBitmapContextCreateImage(tileBitmapContext);

    UIGraphicsEndImageContext();

    return [UIImage imageWithCGImage:theCGImage];

}

Это проверяет, используется ли сетчатка, определяет размер прямоугольника для рисования, выбирает соответствующее базовое изображение в градациях серого, устанавливает режим наложения на наложение, а затем рисует прямоугольник поверх нижнего изображения. Все это делается внутри графического контекста, заключенного в скобки с помощью вызовов BeginImageContext и EndImageContext. Они устанавливают текущий контекст, необходимый для метода UIImage drawRect :. Функции Core Graphics нуждаются в контексте в качестве параметра, который получается при вызове для получения текущего контекста.

И результат выглядит так:

введите описание изображения здесь

person Jim    schedule 11.11.2011

Если вы хотите сохранить альфа-канал исходного изображения, просто добавьте это в код Джима перед прямоугольником заливки:

// Apply mask
CGContextTranslateCTM(tileBitmapContext, 0, rectangle.size.height);
CGContextScaleCTM(tileBitmapContext, 1.0f, -1.0f);

CGContextClipToMask(tileBitmapContext, rectangle, bottomImage.CGImage);
person Scriptease    schedule 12.02.2012

Решение Swift 3, по сути, основанное на ответе Джима с добавлением Scriptease и некоторыми незначительными изменениями:

class func image(bottomImage: UIImage, topImage: UIImage, tileColor: UIColor) -> UIImage? {
    let pixelsHigh: CGFloat = bottomImage.size.height
    let pixelsWide: CGFloat = bottomImage.size.width

    let rectangle = CGRect.init(x: 0, y: 0, width: pixelsWide, height: pixelsHigh)
    UIGraphicsBeginImageContext(rectangle.size);

    bottomImage.draw(in: rectangle)

    if let tileBitmapContext = UIGraphicsGetCurrentContext() {
        tileBitmapContext.setBlendMode(.overlay)
        tileBitmapContext.setFillColor(tileColor.cgColor)
        tileBitmapContext.scaleBy(x: 1.0, y: -1.0)
        tileBitmapContext.clip(to: rectangle, mask: bottomImage.cgImage!)
        tileBitmapContext.fill(rectangle)
        let theCGImage = tileBitmapContext.makeImage()
        UIGraphicsEndImageContext();

        if let theImage = theCGImage {
            return UIImage.init(cgImage: theImage)
        }
    }

    return nil
}
person Duncan Babbage    schedule 05.05.2017