Cocoa Touch - 使用叠加视图添加纹理

发布于 2024-12-14 22:46:34 字数 127 浏览 1 评论 0 原文

我有一组作为 UIView 的图块,它们具有可编程的背景颜色,并且每个图块 可以是不同的颜色。我想为每一个添加纹理,比如侧光斜角。这可以通过覆盖视图或其他方法来完成吗?

我正在寻找不需要为每种情况提供自定义图像文件的建议。

I have a set of tiles as UIViews that have a programmable background color, and each one
can be a different color. I want to add texture, like a side-lit bevel, to each one. Can this be done with an overlay view or by some other method?

I'm looking for suggestions that don't require a custom image file for each case.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

素年丶 2024-12-21 22:46:34

这可能会对某人有所帮助,尽管这是从其他主题中拼凑而成的。
为了创建一个具有任意颜色的斜面平铺图像以用于正常和视网膜显示,我在 Photoshop 中制作了一个斜面图像并将饱和度设置为零,制作了一个名为 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 函数需要上下文作为参数,该参数是通过调用获取当前上下文来获取的。

结果如下所示:

在此处输入图像描述

This may help someone, although this was pieced together from other topics on SO.
To create a beveled tile image with an arbitrary color for normal and for retina display, I made a beveled image in photoshop and set the saturation to zero, making a grayscale image called tileBevel.png

tileBevel.png

I also created one for the retina display ([email protected])

Here is the code:

+ (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];

}

This checks to see if the retina display is used, sizes the rectangle to draw in, picks the appropriate grayscale base image, set the blending mode to overlay, then draws a rectangle on top of the bottom image. All of this is done inside a graphics context bracketed by the BeginImageContext and EndImageContext calls. These set the current context needed by the UIImage drawRect: method. The Core Graphics functions need the context as a parameter, which is obtained by a call to get the current context.

And the result looks like this:

enter image description here

百合的盛世恋 2024-12-21 22:46:34

如果你想保留源图像的 Alpha 通道,只需将其添加到 jim 的代码中填充矩形之前:

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

CGContextClipToMask(tileBitmapContext, rectangle, bottomImage.CGImage);

If you want to preserve the alpha channel of the source image, just add this to jim's code before the fill rect:

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

CGContextClipToMask(tileBitmapContext, rectangle, bottomImage.CGImage);
彼岸花ソ最美的依靠 2024-12-21 22:46:34

Swift 3 解决方案,基本上基于 Jim 的回答,添加了 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
}

Swift 3 solution, essentially based on Jim's answer with Scriptease's addition, and some minor changes:

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
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文