【问题标题】:Chrome Text Effect With Linear Gradient Gives Jagged Edges带有线性渐变的 Chrome 文本效果会产生锯齿状边缘
【发布时间】:2012-12-24 09:18:13
【问题描述】:

我正在尝试在核心图形中生成 chrome 文本效果,但在让它看起来正确时遇到了一些问题。

这是我想要达到的效果:

这是我设法得到的:

如您所见,渐变边缘非常参差不齐。有没有办法在不使用静态 png 进行纹理填充的情况下实现这种效果?

这是我的代码:

- (void)setGradientFill:(UILabel*)label
{
    CGSize textSize = [label.text sizeWithFont:label.font];
    CGFloat width = textSize.width;         // max 1024 due to Core Graphics limitations
    CGFloat height = textSize.height;       // max 1024 due to Core Graphics limitations

    // create a new bitmap image context
    UIGraphicsBeginImageContextWithOptions(CGSizeMake(width, height), YES, 0.0);

    // get context
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetAllowsAntialiasing(context, true);
    CGContextSetShouldAntialias(context, true);

    // push context to make it current (need to do this manually because we are not drawing in a UIView)
    UIGraphicsPushContext(context);

    CGContextSetAllowsAntialiasing(context, YES);
    CGContextSetShouldAntialias(context, YES);

    //draw gradient
    CGGradientRef glossGradient;
    CGColorSpaceRef rgbColorspace;
    size_t num_locations = 5;
    CGFloat locations[5] = { 0.0, 0.5, 0.5, 0.65, 1};
    CGFloat components[20] = {
        1.0, 1.0, 1.0, 1.0,
        1.0, 1.0, 1.0, 1.0,
        0.878, 0.878, 0.878, 0.878,
        0.78, 0.78, 0.78, 1.0,
        1, 1, 1, 1.0
    };
    rgbColorspace = CGColorSpaceCreateDeviceRGB();
    glossGradient = CGGradientCreateWithColorComponents(rgbColorspace, components, locations, num_locations);
    CGPoint start = CGPointMake(0, 0);
    CGPoint end = CGPointMake(width/4, height*1.2);
    CGContextDrawLinearGradient(context, glossGradient, start, end, kCGGradientDrawsAfterEndLocation);

    CGGradientRelease(glossGradient);
    CGColorSpaceRelease(rgbColorspace);

    // pop context
    UIGraphicsPopContext();

    // get a UIImage from the image context
    UIImage *gradientImage = UIGraphicsGetImageFromCurrentImageContext();

    // clean up drawing environment
    UIGraphicsEndImageContext();

    label.textColor = [UIColor colorWithPatternImage:gradientImage];
}

编辑左撇子的建议:

我尝试了您制作的扩展程序(左下图)。由于某种原因,我得到一些非常模糊的文本,边缘有伪影。

我将 UIImage 框架的大小调整为图像以避免内容拉伸:

_test.frame = CGRectMake(_test.frame.origin.x, _test.frame.origin.y, image.size.width, image.size.height);
_test.image = image;

编辑最近的解决方案:

lefteris 的解决方案是最接近的,但您无法真正避免锯齿状渐变边缘。如果可以的话,您应该使用在 Photoshop 中生成的静态 png 来处理纹理(不仅仅是填充的文本),但您可能需要多个版本(就像我一样)才能在每个屏幕上获得正确的效果,因为纹理是根据大小应用的框架不是包含的文本。动态执行是可能的,但似乎有限。

【问题讨论】:

  • 您无需致电UIGraphicsPushContext 即可使其成为最新版本。看看你是从哪里得到它的:它已经当前了。
  • 其实没有这个是不行的。
  • 忘记删除相应的 pop 所以它不起作用,但你是对的,它不需要。

标签: iphone ios uikit core-graphics


【解决方案1】:

使用the UIGraphicsBeginImageContextWithOptions function 并将比例因子设置为0.0

UIGraphicsBeginImageContext 函数调用该函数并将比例因子设置为 1.0,无条件,即使在 Retina (@2x) 设备上也是如此。在 Retina 设备上,您需要 2.0。 0.0 会自动检测正确的比例因子来使用和使用。

【讨论】:

  • 谢谢彼得,我会试一试的。
  • 它有帮助,但边缘仍然是锯齿状的,就像没有抗锯齿一样。我已更新问题以反映 0.0 比例因子设置。
【解决方案2】:

您还应该平滑渐变。

改用这个:

CGFloat locations[5] = { 0.0, 0.45, 0.55, 0.65, 1};

我编辑我的答案以提供不同的解决方案/建议:

我创建了一个渲染 3D 文本的 3D 文本渲染 UIImage Extension,which can be found here

使用该类别扩展,稍作修改,我最终得到了这张图片:

我认为您不应该将渐变创建为背景颜色并将其作为一个整体应用到标签上,因为它也在背景上添加渐变,这使得它看起来不太真实。

我用这些设置创建了上面的图像:

UIImage *my3dImage = [UIImage create3DImageWithText:@"61" Font:[UIFont fontWithName:@"Helvetica-Bold" size:180] ForegroundColor:[UIColor colorWithRed:(255/255.f) green:(255/255.f) blue:(255/255.f) alpha:1.0] ShadowColor:[UIColor blackColor] outlineColor:[UIColor lightGrayColor] depth:4 useShine:YES];

我修改了我的源代码以应用不同的发光效果:

  size_t num_locations = 5;
    CGFloat locations[5] = { 0.0, 0.49, 0.51, 0.65, 1};
    CGFloat gradientComponents[20] = {
        1.0, 1.0, 1.0, 1.0,
        1.0, 1.0, 1.0, 1.0,
        0.878, 0.878, 0.878, 0.878,
        0.78, 0.78, 0.78, 1.0,
        1, 1, 1, 1.0
    };

    CGGradientRef glossGradient = CGGradientCreateWithColorComponents(genericRGBColorspace, gradientComponents, locations, num_locations);
    CGPoint start = CGPointMake(0, expectedSize.height/4);
    CGPoint end = CGPointMake(expectedSize.width/4, expectedSize.height);

原因,我相信我的方法更好,因为它实际上是从文本创建蒙版,然后应用渐变,这意味着只有文本得到渐变而不是背景。

【讨论】:

  • 感谢 Lefteris。我之前确实尝试过这个,并且对于 0.45 组件具有不同值的几个变体。它们要么最终看起来参差不齐,要么过于渐进,这与我提供的示例不符。
  • 感谢 Lefteris 试一试,不确定如何将渐变直接添加到文本填充中会导致问题?
  • 其实我建议用你创建的我创建的类别扩展的图像替换文本。
  • 我根据您的建议更新了问题的详细信息,但效果不如我预期。
  • 您是按原样使用我的代码,并且只替换了渐变代码部分吗?它对我来说很好用!
猜你喜欢
  • 2016-01-10
  • 2020-01-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多