java版:https://my.oschina.net/HJCui/blog/804955
将文本写在图片上,自定义字体,自动换行,自定义行间距。
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Text;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace StringToImg_costomerFont
{
class Program
{
static void Main(string[] args)
{
string text = @"张家口市地处京晋冀蒙交界处,距北京约180公里,这里地势险要,有“塞外山城”之称。冬季白雪皑皑,一片北国风光,山上积雪数尺,整冬不化,是滑雪旅游的天然胜地。全市地势西北高、东南低,阴山山脉横贯中部,将全市划分为坝上、坝下两个自然地理区域。坝上地区地势......";
//string text = @"永和九年,岁在癸丑,暮春之初,会于会稽山阴之兰亭,修禊事也。群贤毕至,少长咸集。此地有崇山峻岭,茂林修竹;又有清流激湍,映带左右,引以为流觞曲水,列坐其次。虽无丝竹管弦之盛,一觞一咏,亦足以畅叙幽情。是日也,天朗气清,惠风和畅,仰观宇宙之大,俯察品类之盛,所以游目骋怀,足以极视听之娱,信可乐也。
//夫人之相与,俯仰一世,或取诸怀抱,悟言一室之内;或因寄所托,放浪形骸之外。虽趣舍万殊,静躁不同,当其欣于所遇,暂得于己,快然自足,曾不知老之将至。及其所之既倦,情随事迁,感慨系之矣。向之所欣,俯仰之间,已为陈迹,犹不能不以之兴怀。况修短随化,终期于尽。古人云:“死生亦大矣。”岂不痛哉!
//每览昔人兴感之由,若合一契,未尝不临文嗟悼,不能喻之于怀。固知一死生为虚诞,齐彭殇为妄作。后之视今,亦犹今之视昔。悲夫!故列叙时人,录其所述,虽世殊事异,所以兴怀,其致一也。后之览者,亦将有感于斯文。--Edit by hjcui on 2016-12-8";
string strSavePath = "C:/test/chn.jpeg";
addStringToImg(strSavePath, text);
text = "Why I Love Beijing";
strSavePath = "C:/test/Eng.jpeg";
AddTextToImg(strSavePath, text);
}
private static void AddTextToImg(string SavePath, string text)
{
int phWidth = 642;
int phHeight = 177;
#region 绘制图片
System.IO.Directory.CreateDirectory(Path.GetDirectoryName(SavePath));
System.Drawing.Imaging.ImageFormat format = System.Drawing.Imaging.ImageFormat.Jpeg;
//Image initImage = (Image)Img.Clone();
//生成新图
//新建一个bmp图片
System.Drawing.Image newImage = new System.Drawing.Bitmap(phWidth, phHeight);
//新建一个画板
System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(newImage);
//设置质量
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
//置背景色
g.Clear(Color.White);
//画图
//g.DrawImage(newImage, new Rectangle(0, 0, phWidth, phHeight), 0, 0, phWidth, phHeight, GraphicsUnit.Pixel);
g.DrawImage(newImage, 0, 0);
//路径
//string path = @"C:\德彪钢笔行书字库.TTF";
string path = @"G:\项目需求\13品牌主页\PingFang Bold.ttf";
//读取字体文件
PrivateFontCollection pfc = new PrivateFontCollection();
pfc.AddFontFile(path);
//实例化字体
float fontSize = 28;
//关于自定义行间距,stackoverflow 中的解释
//Line spacing is a result of the Font you are using.
//You may need to break your DrawString commands up into multiple calls if you need custom line spacing.
int a = pfc.Families[0].GetLineSpacing(FontStyle.Regular);
Font font = new Font(pfc.Families[0], fontSize);
//设置字体
//下面定义一个矩形区域,以后在这个矩形里画上白底黑字
float rectX = -1;
float rectY = -1;
float rectWidth = phWidth;
float rectHeight = phHeight;
//声明矩形域
RectangleF textArea = new RectangleF(rectX, rectY, rectWidth, rectHeight);
//g.FillRectangle(whiteBrush, rectX, rectY, rectWidth, rectHeight);
StringFormat drawFormat = new StringFormat();
//drawFormat.FormatFlags = StringFormatFlags.FitBlackBox;
drawFormat.Alignment = StringAlignment.Center;
//drawFormat.FormatFlags = StringFormatFlags.DisplayFormatControl;
drawFormat.LineAlignment = StringAlignment.Center;
Brush brush = new SolidBrush(Color.FromArgb(135, 135, 135));
g.DrawString(text, font, brush, textArea, drawFormat);
int level = 100; //图像质量 1-100的范围
ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders();
ImageCodecInfo ici = null;
foreach (ImageCodecInfo codec in codecs)
{
if (codec.MimeType == "image/jpeg")
ici = codec;
}
EncoderParameters ep = new EncoderParameters();
ep.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, (long)level);
//保存图
newImage.Save(SavePath, ici, ep);
#endregion
//释放资源
g.Dispose();
newImage.Dispose();
//MemoryStream ms = new MemoryStream();
保存为Jpg类型
//bitmap.Save(ms, ImageFormat.Jpeg);
//Response.Clear();
//Response.ContentType = "image/jpeg";
//Response.BinaryWrite(ms.ToArray());
}
private static void addStringToImg(string SavePath, string text, string strFontPath = null)
{
int phWidth = 642;
int phHeight = 377;
//System.IO.Directory.CreateDirectory(Path.GetDirectoryName(SavePath));
System.Drawing.Imaging.ImageFormat format = System.Drawing.Imaging.ImageFormat.Jpeg;
//新建一个bmp图片
Image newImage = new Bitmap(phWidth, phHeight);
//新建一个画板
Graphics g = Graphics.FromImage(newImage);
//设置质量
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
//置背景色
g.Clear(Color.White);
//画图
//g.DrawImage(newImage, new Rectangle(0, 0, phWidth, phHeight), 0, 0, phWidth, phHeight, GraphicsUnit.Pixel);
g.DrawImage(newImage, 0, 0);
#region 自定义字体
//路径
//string path = @"C:\德彪钢笔行书字库.TTF";
strFontPath = strFontPath ?? @"C:\华康瘦金体W3.TTF";
//读取字体文件
PrivateFontCollection pfc = new PrivateFontCollection();
pfc.AddFontFile(strFontPath);
//实例化字体
float fontSize = 28;
Font font = new Font(pfc.Families[0], fontSize);
#endregion
// 自定义行间距
SizeF fit = new SizeF(phWidth, font.Height);
StringFormat fmt = StringFormat.GenericTypographic;
//fmt.FormatFlags = StringFormatFlags.LineLimit;
//int spacing = (int)(1.5 * font.Height);
int spacing = (int)(10 + font.Height);
//自定义字体颜色
Brush brush = new SolidBrush(Color.FromArgb(65, 65, 65));
int line = 0;
for (int ix = 0; ix < text.Length; )
{
int chars, lines;
g.MeasureString(text.Substring(ix), font, fit, fmt, out chars, out lines);
g.DrawString(text.Substring(ix, chars), font, brush, 0, spacing * line);
++line;
ix += chars;
}
//保存图
newImage.Save(SavePath, ImageFormat.Jpeg);
//释放资源
g.Dispose();
newImage.Dispose();
}
}
}
关于设置行间距有一点要吐槽,vs提示说StringFormat可以设置行间距,但是翻遍了MSDN愣是没找到相关设置。被微软忽悠了一把。
微软支持自动换行,但是不能设置行间距,效果图
自定义行距效果图