cocos2dx字体描边与PS字体描边有什么区别

2015年01月29日 11:48 0 点赞 0 评论 更新于 2025-11-21 15:42

我们都知道Cocos2d-x和PS都具备字体描边的功能,那么Cocos2d-x字体描边与PS字体描边究竟有什么区别呢?接下来我们将详细探讨。

一、Cocos2d-x字体描边的实现方式

在不考虑效果和效率的前提下,Cocos2d-x字体描边有三种实现方式:

  1. 利用CCLabelTTF制作文字描边和阴影效果。
  2. 利用CCRenderTexture渲染纹理的方式生成带有描边效果的文字。
  3. 利用shader来实现,通过Cocos2d-x中CCGLProgram类与OpenGL绘图机制中的着色器交互达成。

第三种方式笔者尚未尝试,但基于shader强大的特效功能,实现应该不成问题。后续笔者还会撰写一篇关于使用shader改变纹理颜色以实现特殊效果的文章。现在我们主要研究前两种方式,从原理上来说,前两种方式都是利用多个CCLabelTTF的重叠来实现的,只不过第二种方式是使用CCLabelTTF绘制了一个带有描边效果的文字图片。

1. 利用CCLabelTTF制作文字描边和阴影效果

网上有大量博客对这种方式进行了详细讲解,大家可以参考这个链接:https://www.taikr.com/

文字描边原理

创建4个用于描边的CCLabelTTF和一个正文主体CCLabelTTF。先绘制描边的label,将其颜色设置为所需的描边色,并分别在目标位置进行上下左右4个方向的偏移,最后覆盖上正文主体label。

以下是实现代码:

/*
* string     文本
* fontName   文本字体类型
* fontSize   文本大小
* color3     文本颜色
* lineWidth  所描边的宽度
*/
CCLabelTTF* HelloWorld::textAddStroke(const char* string, const char* fontName, float fontSize, const ccColor3B &color3, float lineWidth)
{
/* 正文CCLabelTTF */
CCLabelTTF* center = CCLabelTTF::create(string, fontName, fontSize);
center->setColor(color3);

/* 描边CCLabelTTF 上 */
CCLabelTTF* up = CCLabelTTF::create(string, fontName, fontSize);
up->setColor(ccBLACK);
up->setPosition(ccp(center->getContentSize().width * 0.5, center->getContentSize().height * 0.5 + lineWidth));
center->addChild(up, -1);

/* 描边CCLabelTTF 下 */
CCLabelTTF* down = CCLabelTTF::create(string, fontName, fontSize);
down->setColor(ccBLACK);
down->setPosition(ccp(center->getContentSize().width * 0.5, center->getContentSize().height * 0.5 - lineWidth));
center->addChild(down, -1);

/* 描边CCLabelTTF 左 */
CCLabelTTF* left = CCLabelTTF::create(string, fontName, fontSize);
left->setPosition(ccp(center->getContentSize().width * 0.5 - lineWidth, center->getContentSize().height * 0.5));
left->setColor(ccBLACK);
center->addChild(left, -1);

/* 描边CCLabelTTF 右 */
CCLabelTTF* right = CCLabelTTF::create(string, fontName, fontSize);
right->setColor(ccBLACK);
right->setPosition(ccp(center->getContentSize().width * 0.5 + lineWidth, center->getContentSize().height * 0.5));
center->addChild(right, -1);

return center;
}

阴影效果

阴影效果更为简单,只需两个label,一个用于阴影的label和一个正文label,设置好阴影label的颜色、透明度和位置偏移即可。

以下是实现代码:

/*
* string         文本
* fontName       文本字体类型
* fontSize       文本大小
* color3         文本颜色
* shadowSize     阴影大小
* shadowOpacity  阴影透明度
*/
CCLabelTTF* HelloWorld::textAddShadow(const char* string, const char* fontName, float fontSize, const ccColor3B &color3, float shadowSize, float shadowOpacity)
{
/* 阴影label */
CCLabelTTF* shadow = CCLabelTTF::create(string, fontName, fontSize);
shadow->setColor(ccBLACK);
shadow->setOpacity(shadowOpacity);

/* 正文label */
CCLabelTTF* center = CCLabelTTF::create(string, fontName, fontSize);
center->setColor(color3);
center->setPosition(ccp(shadow->getContentSize().width * 0.5 - shadowSize, shadow->getContentSize().height * 0.5 + shadowSize));
shadow->addChild(center);

return shadow;
}

2. 利用CCRenderTexture渲染纹理的方式生成带有描边效果的文字

这种方式的难点在于很多人对OpenGL的绘图着色机制不太了解,但实际上这里只涉及到一点颜色混合的知识。在绘图时,OpenGL会将源颜色和目标颜色各自取出,并分别乘以一个系数(源颜色乘以的系数称为“源因子”,目标颜色乘以的系数称为“目标因子”),然后进行运算得到新的颜色值,并按照新的颜色来绘制。

例如,在RGB格式中,原来的颜色是(255,0,0)(红色),目标颜色是(0,255,0)(绿色),若系数为{1,0},运算方式为颜色的叠加,那么新的颜色为(255,0,0)1 + (0,255,0)0 = (255,0,0)(红色),即完全不使用目标颜色的值,相当于颜色没有变化。系数中源因子为前者1,目标因子为后者0,这就是{1,0}的混合机制。

在Cocos2d-x中,可渲染的节点都是CCNode的子类,如精灵、场景、文本等。CCNode有一个渲染混色的函数glBlendFunc()setBlendFunc(),操作的是ccBlendFuncccBlendFunc有两个调节变量,例如ccBlendFunc func = { GL_SRC_ALPHA, GL_ONE},这里的调节变量就是前面所说的系数:

  • GL_SRC_ALPHA:表示使用源颜色的alpha值作为源因子。
  • GL_ONE:表示使用1.0作为因子,实际上相当于完全使用这种颜色参与混合运算。

这类参数有很多,大家可以跟踪引擎代码内部查看。

CCRenderTexture生成描边字体的原理是,它可以被看作是一张纹理画布,我们可以在这张画布上进行绘制。当绘制完成后,就会生成一张纹理。具体做法是,在画布上用一个label在不同的位置不断绘制,类似于第一种方式,在画布上绘制label时,在目标位置的360个方向绘制多个label并使其重叠,最后通过画布生成带有描边文字的纹理图,再用这张纹理图生成一个精灵放到场景中。

以下是实现代码:

CCTexture2D* FlyBloodLabel::createStrokeTexture(const char* value, float strokeValue, ccColor3B color)
{
// float fontSize = m_fontSize - 2 * strokeSize;
/* 创建一个CCLabelTTF,含有期望字体样式,作为画笔 */
CCLabelTTF *label = CCLabelTTF::create(value, "Arial", EFFECT_LABEL_FONT_SIZE);

/* 通过label的大小来设置最终生成的纹理图片的大小,strokeValue为描边字体的偏移量,影响粗细 */
CCSize textureSize = label->getContentSize();
textureSize.width += 2 * strokeValue;
textureSize.height += 2 * strokeValue;

/* 监测OpenGl的错误状态 */
glGetError();

/* 创建一张纹理画布 */
CCRenderTexture *rt = CCRenderTexture::create(textureSize.width, textureSize.height);
if (!rt)
{
CCLog("create render texture failed !!!!");
addChild(label);
return 0;
}

/* 设置描边的颜色 */
label->setColor(color);

/*
* 拿到源文字的混色机制,存储以备恢复,并设置新的目标混色机制
* 混色机制设为:源颜色透明度(影响亮度)和目标颜色(影响颜色)
*/
ccBlendFunc originalBlend = label->getBlendFunc();
ccBlendFunc func = { GL_SRC_ALPHA, GL_ONE };
label->setBlendFunc(func);

/* 这是自定义的一些调整,倾斜了一点 */
label->setAnchorPoint(ccp(0.5, 0.5));
label->setRotationX(15);

/* 张开画布,开始绘画 */
rt->begin();
for (int i = 0; i < 360; i += 5)
{
float r = CC_DEGREES_TO_RADIANS(i);
label->setPosition(ccp(textureSize.width * 0.5f + sin(r) * strokeValue, textureSize.height * 0.5f + cos(r) * strokeValue));
/* CCRenderTexture的用法,在begin和end之间visit的纹理,都会画在CCRenderTexture里面 */
label->visit();
}

/* 恢复原始的label并绘制在最上层 */
label->setColor(ccWHITE);
label->setBlendFunc(originalBlend);
label->setPosition(ccp(textureSize.width * 0.5f, textureSize.height * 0.5f));
label->visit();

/* 在画布上绘制结束,此时会生成一张纹理 */
rt->end();

/* 取出生成的纹理,添加抗锯齿打磨,并返回 */
CCTexture2D *texture = rt->getSprite()->getTexture();
texture->setAntiAliasTexParameters();
return texture;
}

3. Shader方式

除了上述两种方式,还可以使用Shader来实现字体描边,不过目前笔者还在研究中。Shader的特效功能非常强大,后续会逐步深入学习。

二、PS字体描边

在图片的后期处理中,图片上的文字就如同男人的手表、女人的首饰一样,适当而精彩的文字能为图片起到点睛的装饰作用。文字的添加并非简单地打字上图,无论是构图、编排还是修饰都需要反复斟酌。很多软件也推出了文字修饰功能,文字描边就是比较常用的一种。文字添加描边后会更加立体和突出,但不同软件完成文字描边的方法不尽相同。下面我们对Photoshop CS3和美图秀秀这两款常用图片处理软件的文字描边功能进行横向测评。

1. 评测过程 - Photoshop(以下简称PS,收费软件暂不提供下载)

在PS里给文字添加描边,首先点击左侧功能栏中的文字图标,拖拽出文字编辑框,键入文字时可以更换字体及其大小模式(浑厚、犀利等)。不过,PS中只能使用本地字体,若需要喜欢的字体,需去网上下载安装。

在PS中实现文字描边有两种方法:

方法1:利用编辑菜单 - 描边进行描边

  1. 输入文字。
  2. 选择“图层” - 栅格化 - 文字。
  3. 将文字载入选区,选择“编辑”菜单 - 描边。
  4. 在“描边”对话框中设置描边的宽度及颜色等,点击“确定”完成描边。

方法2:利用图层样式进行描边

  1. 输入文字。
  2. 双击图层后面的蓝色区域,弹出“图层样式”对话框。
  3. 在样式下面勾选“描边”,再在“混合选项”栏进行相关设置。
  4. 设置完成后,点击“好”按钮完成描边。

相比之下,方法2比较好用,在修改颜色和描边粗细时可以实时预览效果。下面详细介绍在图层样式中进行文字描边的相关内容。

在描边编辑框中,功能非常强大。描边粗细可自行调节,还设有描边的位置选项(外部、内部、居中),大多常用的是外部描边。此外,还有一些混合模式和填充类型,相对比较复杂,这里不再详细介绍。至于描边的颜色,可以在颜色选择器中调节,也可以在颜色状态下使用取色笔拾取图片上的某种颜色作为描边颜色。

三、总结

通过了解Cocos2d-x字体描边与PS字体描边的过程,我们可以发现它们最大的区别在于实现方法不同。Cocos2d-x主要通过编程的方式,利用引擎提供的类和方法来实现字体描边;而PS则是在图形处理软件中,通过图形化的界面操作来完成字体描边。

作者信息

feifeila

feifeila

共发布了 3994 篇文章