要实现的功能:一张照片,一张照片边框,一张背景相框,和几段文字合成为一张图片并保存。
先贴最终效果:
核心就是GDI+中的几个方法(DrawImage,DrawString,DrawLine)。难点或者说麻烦一点的地方是头像照片和文字在背景图上的定位。
直接贴上主方法:(抱歉,使用代码块就无法显示)
{
double percent = 0.44;//397-(211+10)=176,176/397=44%--从TO(文字区域211,距离右侧10)开始的左侧区域占总区域397的百分比
double wz_percent = 0.275;//70/255=0.275--文字距离上边70占总高度的百分比
int fLen = 24;//"愿"和正文之间的距离
int f_l_Len = 20;//字顶与横线之间距离
int lLen = 30;//行距
int l_r_Len = 27;//横线与最右侧边框的距离
int w_Len = 7;//边框的宽度
try
{
Image imgPic = GetImage(picPath);
Image imgBg = GetImage(bgPath);
Image imgWhiteBg = GetImage(whiteBgPath);
Image newBG = imgBg.GetThumbnailImage(imgBg.Width, imgBg.Height, null, new IntPtr());
Graphics g = Graphics.FromImage(imgBg);
g.Clear(Color.White);
double x_pic = (imgBg.Width * percent - imgPic.Width) / 2;
double y_pic = (imgBg.Height - imgPic.Height) / 2;
double x_white = x_pic - w_Len;
double y_white = y_pic - w_Len;
double x_wz = percent * imgBg.Width;
double y_wz = wz_percent * imgBg.Height;
// 指定高质量的双三次插值法。执行预筛选以确保高质量的收缩。此模式可产生质量最高的转换图像。
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.CompositingQuality = CompositingQuality.HighQuality;
// 指定高质量、低速度呈现。
g.SmoothingMode = SmoothingMode.HighQuality;
//背景
g.DrawImage(newBG, 0, 0, imgBg.Width, imgBg.Height);
//照片
int imgY = (imgBg.Height - imgPic.Height - w_Len * 2) / 2;
g.DrawImage(imgPic, (int)x_pic, (int)y_pic, imgPic.Width, imgPic.Height);//x,y坐标根据初始css文件算出:x=left 8+padding 7=15;y=padding 7+ top 56=63
//照片边框
g.DrawImage(imgWhiteBg, (int)x_white, (int)y_white, imgPic.Width + w_Len * 2, imgPic.Height + w_Len * 2);//x,y坐标根据初始css文件算出:x=left 8;y=top 56,宽高各比照片大14px
//文字
Font fTo = new Font(new FontFamily("Tahoma"), 14, FontStyle.Regular, GraphicsUnit.Pixel);
SolidBrush sbTo = new SolidBrush(Color.Black);
g.DrawString("TO:", fTo, sbTo, (int)x_wz, (int)y_wz);
g.DrawString(to, fTo, sbTo, (int)x_wz + fLen, (int)y_wz);
Font fWish = new Font(new FontFamily("Tahoma"), 14, FontStyle.Regular, GraphicsUnit.Pixel);
SolidBrush sbWish = new SolidBrush(Color.Black);
g.DrawString("愿:", fWish, sbWish, (int)x_wz, (int)y_wz + lLen);
Font f = new Font(new FontFamily("Tahoma"), 14, FontStyle.Regular, GraphicsUnit.Pixel);
SolidBrush sb = new SolidBrush(Color.Black);
//第一条横线:TO:___________
g.DrawLine(new Pen(Color.Black), (int)x_wz + fLen, (int)y_wz + f_l_Len, imgBg.Width - l_r_Len, (int)y_wz + f_l_Len);
List<string> list = GetContent(content);
for (int i = 1; i < list.Count + 1; i++)
{
g.DrawString(list[i - 1], f, sb, (int)x_wz + fLen, (int)y_wz + i * lLen);
g.DrawLine(new Pen(Color.Black), (int)x_wz + fLen, (int)y_wz + f_l_Len + i * lLen, imgBg.Width - l_r_Len, (int)y_wz + f_l_Len + i * lLen);
}
g.Dispose();
//关键质量控制
ImageCodecInfo jgpEncoder = GetImageEncoder(ImageFormat.Jpeg);
EncoderParameters ep = new EncoderParameters(1);
ep.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 85L);
DirectoryInfo dir = new DirectoryInfo(savePath+userID.ToString());
if (!dir.Exists)
{
dir.Create();
}
string fileName = userID.ToString() + "_" + picID.ToString() + ".jpg";
if (!new FileInfo(savePath + userID.ToString() + "/" + fileName).Exists)
{
imgBg.Save(savePath + userID.ToString() + "/" + fileName, jgpEncoder, ep);
}
return fileName;
}
catch (Exception)
{
return string.Empty;
}
}
3 double percent = 0.44;//397-(211+10)=176,176/397=44%--从TO(文字区域211,距离右侧10)开始的左侧区域占总区域397的百分比
4 double wz_percent = 0.275;//70/255=0.275--文字距离上边70占总高度的百分比
5
6 int fLen = 24;//"愿"和正文之间的距离
7 int f_l_Len = 20;//字顶与横线之间距离
8 int lLen = 30;//行距
9 int l_r_Len = 27;//横线与最右侧边框的距离
10 int w_Len = 7;//边框的宽度
11
12 try
13 {
14 Image imgPic = GetImage(picPath);
15 Image imgBg = GetImage(bgPath);
16 Image imgWhiteBg = GetImage(whiteBgPath);
17
18 Image newBG = imgBg.GetThumbnailImage(imgBg.Width, imgBg.Height, null, new IntPtr());
19 Graphics g = Graphics.FromImage(imgBg);
20
21 g.Clear(Color.White);
22
23
24 double x_pic = (imgBg.Width * percent - imgPic.Width) / 2;
25 double y_pic = (imgBg.Height - imgPic.Height) / 2;
26
27 double x_white = x_pic - w_Len;
28 double y_white = y_pic - w_Len;
29
30 double x_wz = percent * imgBg.Width;
31 double y_wz = wz_percent * imgBg.Height;
32
33
34
35 // 指定高质量的双三次插值法。执行预筛选以确保高质量的收缩。此模式可产生质量最高的转换图像。
36 g.InterpolationMode = InterpolationMode.HighQualityBicubic;
37 g.CompositingQuality = CompositingQuality.HighQuality;
38
39 // 指定高质量、低速度呈现。
40 g.SmoothingMode = SmoothingMode.HighQuality;
41
42 //背景
43 g.DrawImage(newBG, 0, 0, imgBg.Width, imgBg.Height);
44
45 //照片
46 int imgY = (imgBg.Height - imgPic.Height - w_Len * 2) / 2;
47 g.DrawImage(imgPic, (int)x_pic, (int)y_pic, imgPic.Width, imgPic.Height);//x,y坐标根据初始css文件算出:x=left 8+padding 7=15;y=padding 7+ top 56=63
48
49 //照片边框
50 g.DrawImage(imgWhiteBg, (int)x_white, (int)y_white, imgPic.Width + w_Len * 2, imgPic.Height + w_Len * 2);//x,y坐标根据初始css文件算出:x=left 8;y=top 56,宽高各比照片大14px
51
52 //文字
53 Font fTo = new Font(new FontFamily("Tahoma"), 14, FontStyle.Regular, GraphicsUnit.Pixel);
54 SolidBrush sbTo = new SolidBrush(Color.Black);
55 g.DrawString("TO:", fTo, sbTo, (int)x_wz, (int)y_wz);
56 g.DrawString(to, fTo, sbTo, (int)x_wz + fLen, (int)y_wz);
57
58
59 Font fWish = new Font(new FontFamily("Tahoma"), 14, FontStyle.Regular, GraphicsUnit.Pixel);
60 SolidBrush sbWish = new SolidBrush(Color.Black);
61 g.DrawString("愿:", fWish, sbWish, (int)x_wz, (int)y_wz + lLen);
62
63
64
65 Font f = new Font(new FontFamily("Tahoma"), 14, FontStyle.Regular, GraphicsUnit.Pixel);
66 SolidBrush sb = new SolidBrush(Color.Black);
67
68 //第一条横线:TO:___________
69 g.DrawLine(new Pen(Color.Black), (int)x_wz + fLen, (int)y_wz + f_l_Len, imgBg.Width - l_r_Len, (int)y_wz + f_l_Len);
70
71
72 List<string> list = GetContent(content);
73 for (int i = 1; i < list.Count + 1; i++)
74 {
75 g.DrawString(list[i - 1], f, sb, (int)x_wz + fLen, (int)y_wz + i * lLen);
76 g.DrawLine(new Pen(Color.Black), (int)x_wz + fLen, (int)y_wz + f_l_Len + i * lLen, imgBg.Width - l_r_Len, (int)y_wz + f_l_Len + i * lLen);
77 }
78
79 g.Dispose();
80
81 //关键质量控制
82 ImageCodecInfo jgpEncoder = GetImageEncoder(ImageFormat.Jpeg);
83 EncoderParameters ep = new EncoderParameters(1);
84 ep.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 85L);
85
86 DirectoryInfo dir = new DirectoryInfo(savePath+userID.ToString());
87 if (!dir.Exists)
88 {
89 dir.Create();
90 }
91
92
93 string fileName = userID.ToString() + "_" + picID.ToString() + ".jpg";
94 if (!new FileInfo(savePath + userID.ToString() + "/" + fileName).Exists)
95 {
96 imgBg.Save(savePath + userID.ToString() + "/" + fileName, jgpEncoder, ep);
97 }
98 return fileName;
99
100 }
101 catch (Exception)
102 {
103 return string.Empty;
104 }
105 }
其中一些数值常量是按照CSS测量或计算出来的。第36-37,第81行-84行代码保证了生成最终图片的质量。由于我不希望做成一个定宽定高的模式化计算方法,所以很多位置都是根据原始图片的宽高动态生成的,这样能保证不论多大的图片都可以生成在正确的位置。如果你喜欢的话,可以在左上角加上方块格子的图片,这样,明信片就完成了~至于一些中英文字符串截取之类的方法就不贴了,有何不足之处大家尽管指教。