当我们需要在具有丰富色调的图片上显示文本时,由于背景颜色的变化,文本往往无法清晰呈现。就像很多早期的电影用纯白字幕一样,字幕在蓝天白云下往往并不清晰。此时,我们需要文本掩码来突出文本的功效,就像这样。
(动画截图由黄少文提供)
那么,如何达到这样的疗效呢?下面我简单介绍一下今天常用的几种技巧。最后,我想介绍一下我设想的一个简单实用的实现。
一般方式
第一个想法:文字就是图片
将文本块转换为可写位图
遍历可写位图的像素,确定每个像素点的值css3文字描边,最终达到遮罩的效果。
请参阅 Silverlight 字体遮罩
诺比评论:
这种思维将文字转换成图片,根据效率识别图片上的每一个像素点,最终效果简单,如下图所示。
第二个想法:像素着色器
这种方法的基本思想是:假设只有像素着色器应用于 TextBlock,那么 TextBlock 是一个圆,文本所在的像素的 alpha 分量必须小于 0,否则必须是透明像素。判断如果当前像素的任何像素是不透明的,则表示需要遮罩该像素,否则将输出文本颜色。由于需要知道相邻像素,因此还需要传入 TextBlock 的实际宽度和实际高度。这样,当前位置的 x+ 1/width 就是相邻像素的坐标,可以使用 tex2D 函数提取其颜色值。您还需要输入蒙版的颜色以及文本的颜色。
请参阅“具有文本遮罩效果的 SILVERLIGHT 像素着色器编译简明手册”
诺比评论:
它仍然是一个“大炮击中错误”的想法,文本是逐像素处理的。与 Idea 1 的唯一区别是使用像素着色器,它们“看起来”高效且快速地将一些工作卸载到 GPU。但是css3文字描边,如果禁用了硬件加速怎么办?它与 1 相同。以下是该方法功效的屏幕截图。
第三个思路:GDI+路径绘制
此方法不再是逐像素处理。基本思想是将文本字符串添加到 GDI+ 绘制路径 (图形路径),然后添加 DrawPath()。使用不同的画笔,这种方式可以“绘制”出特别华丽的蒙版效果,就像这样。
诺比评论:
这是扩展的最佳方式。由于GDI+的中间特性,可以使用不同的画笔(如纹理,渐变和多个绘图)来制作特别精致的蒙版和阴影。唯一的遗憾是代码量很大(远少于上面的2个)。
请参阅文章“C# 水印图像 + 文本掩码 + 发光文本。查看图片和演示”
有关该方法的中间功效设计,请参阅文章“大纲文本”(Code Project “2009 年 9 月最佳C++/MFC 文章”竞赛优胜文章)。
做诺比的简单方法
又到了诺比的懒惰时间。
看完以上设计思路,你是不是觉得迷茫?还是眼花缭乱?这是我们唯一的办法吗?如果需要“描”文本,是否必须“绘制”?
事实上,这是完全没有必要的。当我在 Cottage Safari 中时,我介绍了一种通过反复绘制文本来实现荧光笔效果的简单方法(请参阅“逐步播放控件:TabControl - 从制作 Cottage Safari 窗体开始”)。
如下图所示。当底部文本与顶部文本相差 1px 时,将显示不同的阴影/高光效果。因此,如果我们扩展这个想法,并将向上,向下,向左和向右四个方向的错误结合起来,我们将获得“笔画”文本的效果,就像右图末尾所示的效果一样。
接下来,在 GDI+ 上实现它。
// Code by Conmajia
// txtPoint是绘制文字的定位点
txtPoint.Offset(-1, 0); // 绘制左背景文字
e.Graphics.DrawString(this.Text, this.Font, backBrush, txtPoint);
txtPoint.Offset(2, 0); // 绘制右背景文字
e.Graphics.DrawString(this.Text, this.Font, backBrush, txtPoint);
txtPoint.Offset(-1, -1); // 绘制下背景文字
e.Graphics.DrawString(this.Text, this.Font, backBrush, txtPoint);
txtPoint.Offset(0, 2); // 绘制上背景文字
e.Graphics.DrawString(this.Text, this.Font, backBrush, txtPoint);
txtPoint.Offset(0, -1); // 定位点归位
// 绘制前景文字
e.Graphics.DrawString(this.Text, this.Font, foreBrush, txtPoint);
请享受以下功效
结论
很多时候,当我们遇到问题时,我们不一定要完全跟随问题。就像这一次,我们需要“划”,但谁说要“画”边缘呢?我们只要功效,不求过程,所以要走出问题错觉的桎梏,才能获得更广阔的视野。
阐明
因为我的基础很差(大佬们别喷),所以今天想把文字显示在图片的上方,并对图片进行模糊处理。 结果当图片模糊的时候,也就是实现毛玻璃效果之后,图片上的文字也模糊了。 这个问题其实可以通过使用伪元素来解决,但是由于个人原因,这里不能使用伪元素。
然后我找到了滤镜(filter)属性,这个属性主要是用在图片上,实现一些特殊效果。
然后用滤镜属性模糊后,发现他的疗效如右图:
这时候文字显示正常了,图片也模糊了,但是我又遇到了一个问题,就是如果图片是黑色的,即使模糊了,文字显示的疗效也很差,这样如下图:
当我看到疗效时,我傻眼了。 由于文字是红色的,我只是将图片调暗一点。
于是我在滤镜(filter)属性中使用了一行代码css3 模糊效果,直接将图片变暗:
这时我感觉比那些毛玻璃和高斯模糊好多了。
这里主要用到的是过滤器(filter)属性。 具体教程请参考:菜鸟教程
代码
图片特效
.father {
height: 100%;
height: 100px;
text-align: center;
line-height: 100%;
position: relative;
background-image: url('https://pic.zeyiwl.cn/yunimg/20220217173458.png');
background-size: 100% 100%;
}
.lvjing {
width: 100%;
height: 100px;
background: inherit;
/* 背景模糊毛玻璃效果 */
/* -webkit-filter: blur(7px);
-moz-filter: blur(7px);
-ms-filter: blur(7px);
-o-filter: blur(7px);
filter: blur(7px);
filter: progid: DXImageTransform.Microsoft.Blur(PixelRadius=4, MakeShadow=false); */
/* 变暗效果 */
filter: brightness(50%);
}
.son {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
color: #fff;
}
正常显示的文本内容
注意
背景:继承; 这个必须有,用于选择要操作的背景图片。
滤镜和原始背景图片(父)框的宽度和高度必须保持相同,否则会很乱。
如果背景图片正常显示css3 模糊效果,请添加:background-size: 100% 100%; 财产。
发表评论