TextVisualEffects
渐变色
用不同颜色的文字显示图像
3D文字
源码:
#include <easyx.h>
#include <conio.h>
// 选择文件
// isSave标志着是否为保存模式
const WCHAR* SelectFile(bool isSave = false)
{
OPENFILENAME ofn;
static WCHAR szFile[256];
static WCHAR szFileTitle[256];
memset(&ofn, 0, sizeof(ofn));
ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = GetConsoleWindow();
ofn.lpstrFilter = L"PictureFile (*.*)\0*.*\0";
ofn.nFilterIndex = 1;
ofn.lpstrFile = szFile;
ofn.nMaxFile = sizeof(szFile);
ofn.lpstrFileTitle = szFileTitle;
ofn.nMaxFileTitle = sizeof(szFileTitle);
ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_EXPLORER;
if (isSave)
{
if (GetSaveFileName(&ofn))
{
return szFile;
}
}
else
{
if (GetOpenFileName(&ofn))
{
return szFile;
}
}
return _T("");
}
// 图像转文字图像
// str 用以替代的文字
// srcimg 原图像
// outimg 输出在的图像指针
// nextline 是否允许文字换行,换行好像有点bug
void ImageToTextImage(LPCTSTR str, IMAGE srcimg, IMAGE* outimg, bool nextline)
{
IMAGE* pOld = GetWorkingImage();
IMAGE imgText(srcimg.getwidth(), srcimg.getheight());
SetWorkingImage(&imgText);
int w = textwidth(str);
int h = textheight(str);
int text_repeat;
text_repeat = (getwidth() / w + 1) * (getheight() / h + 1);
if (nextline)
{
int word_index = 0;
for (int i = 0; i < text_repeat * lstrlen(str); i++)
{
if (getx() >= getwidth())
moveto(0, gety() + h);
outtext(str[word_index]);
word_index++;
if (word_index > lstrlen(str))
word_index = 0;
}
}
else
{
for (int i = 0; i < text_repeat; i++)
{
if (getx() >= getwidth())
moveto(0, gety() + h);
outtext(str);
}
}
for (int i = 0; i < getwidth(); i++)
{
for (int j = 0; j < getheight(); j++)
{
if (getpixel(i, j) != BLACK)
{
SetWorkingImage(&srcimg);
int color = getpixel(i, j);
SetWorkingImage(&imgText);
putpixel(i, j, color);
}
}
}
SetWorkingImage(outimg);
putimage(0, 0, &imgText);
SetWorkingImage(pOld);
}
// 输出渐变色文字(只渐变蓝色值)
// str 文字
// blue1,2 起始蓝色值和结束蓝色值(0~255)
void OutGradientText(LPCTSTR str, int blue1, int blue2)
{
IMAGE* pOld = GetWorkingImage();
LOGFONT font;
gettextstyle(&font);
int width = textwidth(str);
int height = textheight(str);
IMAGE* img = new IMAGE(width, height);
SetWorkingImage(img);
setbkcolor(WHITE);
cleardevice();
settextstyle(&font);
settextcolor(BLUE);
outtext(str);
int blue = blue1;
int add = (blue2 - blue1) / width;
for (int x = 0; x < width; x++)
{
for (int y = 0; y < height; y++)
{
if (getpixel(x, y) != WHITE)
{
putpixel(x, y, RGB(0, 0, blue));
}
}
blue += add;
}
SetWorkingImage(pOld);
putimage(0, 0, img);
delete img;
}
// 输出3D文字
// str 文字
// x,y 输出位置
void Out3DTextXY(LPCTSTR str, int x, int y)
{
IMAGE* pOld = GetWorkingImage();
IMAGE img;
SetWorkingImage(&img);
settextstyle(50, 0, L"Impact");
int nWidth3D = 3; // 3D边框加宽
int w = textwidth(str) + nWidth3D;
int h = textheight(str) + nWidth3D;
Resize(&img, w, h);
outtext(str);
// 1.描边
// 得到所有边的点位置信息
// 边点结构体
struct Side
{
// 边点位置
int x;
int y;
// 标志上下左右是否为空
bool up = false;
bool down = false;
bool left = false;
bool right = false;
};
Side* sides = new Side[w * h];
int nSides = 0;
#define isTextPixel(i,j) getpixel(i, j) != BLACK
// 遍历图像统计所有边点信息
for (int i = 0; i < w; i++)
{
for (int j = 0; j < h; j++)
{
if (isTextPixel(i, j))
{
bool bSide = false;
if (!isTextPixel(i, j - 1))
{
sides[nSides].up = true;
bSide = true;
}
if (!isTextPixel(i, j + 1))
{
sides[nSides].down = true;
bSide = true;
}
if (!isTextPixel(i - 1, j))
{
sides[nSides].left = true;
bSide = true;
}
if (!isTextPixel(i + 1, j))
{
sides[nSides].right = true;
bSide = true;
}
if (bSide)
{
sides[nSides].x = i;
sides[nSides].y = j;
nSides++;
}
}
}
}
// 2.根据边点信息重建图像
cleardevice();
for (int i = 0; i < nSides; i++)
{
// 基础边框宽度
int width = 1;
if (sides[i].right)
{
width += nWidth3D;
}
for (int j = 0; j < width; j++)
{
putpixel(sides[i].x + j, sides[i].y, WHITE);
}
}
delete[] sides;
SetWorkingImage(pOld);
putimage(x, y, &img);
}
int main()
{
initgraph(640, 480);
outtext(L"按1测试渐变色文字,按2测试用不同颜色的文字显示图像,按3测试3D文字");
moveto(0,20);
outtext(L"制作:huidong <mailkey@yeah.net> 2020.10.18");
char input = _getch();
cleardevice();
TCHAR str[1024] = { 0 };
IMAGE img;
switch (input)
{
case '1':
InputBox(str, 1024, L"输入要测试的文字,最好稍微长一点");
setbkcolor(WHITE);
cleardevice();
OutGradientText(str, 0, 255);
break;
case '2':
MessageBox(GetHWnd(), L"按确定后选择要用以测试的图片", L"提示", MB_OK);
loadimage(&img, SelectFile());
InputBox(str, 1024, L"输入要用以测试的文字,最好不要太长");
if (MessageBox(GetHWnd(), L"是否允许文字换行", L"提示", MB_OKCANCEL) == IDOK)
ImageToTextImage(str, img, &img, true);
else
ImageToTextImage(str, img, &img, false);
MessageBox(GetHWnd(), L"生成的图像可能无法在窗口中完整显示,但您稍后可以选择保存生成的图像。", L"提示", MB_OK);
putimage(0, 0, &img);
if (MessageBox(GetHWnd(), L"是否存储生成的图像", L"提示", MB_OKCANCEL) == IDOK)
saveimage(SelectFile(true), &img);
break;
case '3':
InputBox(str, 1024, L"输入要测试的文字,中文可能效果不佳");
Out3DTextXY(str, 20, 20);
break;
}
while (true);
closegraph();
return 0;
}
release:
GradientColorText.zip