Cocoa Touch - добавление текстуры с наложением - PullRequest
2 голосов
/ 10 ноября 2011

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

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

Ответы [ 3 ]

2 голосов
/ 11 ноября 2011

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

tileBevel.png

Я также создал один для дисплея сетчатки (tileBevel@2x.png)

Вот код:

+ (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:@"tileBevel@2x.png"];        
    }
    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 нужен контекст в качестве параметра, который получается вызовом для получения текущего контекста.

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

enter image description here

1 голос
/ 12 февраля 2012

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

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

CGContextClipToMask(tileBitmapContext, rectangle, bottomImage.CGImage);
0 голосов
/ 05 мая 2017

Решение 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
}
...