上一章讲了如何生成二维码,这里才讲如何生成海报,有时候我们需要把海报做出推广的效果,让客户用着舒服,这个时候就需要生成海报,废话不多说,直接上代码
前端:只是放一个图片的路径(为了方便)
<div class="row" style="width:250Px;margin:auto">
<img id="imgPoster" src="@Url.Action("ShowImg", "Home")" />
</div>
后台:
public ActionResult Index()
{
return View();
}
/// <summary>
/// 显示图片
/// </summary>
/// <returns></returns>
public ActionResult ShowImg()
{
string url = "https://www.baidu.com";
//var bytes = QrCode.GetQrCode(url);
//Stream imgStream = new MemoryStream(bytes);
//return File(imgStream, "image/jpeg");
QrCode code = new QrCode();
var imgStream = code.GetRecommendQrCodeText("", url, "张三");//这里第一个参数传递空,后面用了判断,如果有图片直接拿自己的链接即可
return File(imgStream, "image/jpeg");//还是一样转换成流的形式
}
接下来就是用画布来画文字,图片,头像,二维码,
看着下面那么多代码不要怕,很多都是把资源画到画布上面去,直接拿过去copy即可
里面的方法已经注释的很清晰了
需要注意的是TemplateImageBytes这个对象声明时,获取画布,我在里面放了一张背景图,如果你有好看的图片自己放上去即可
public class QrCode
{
/// <summary>
/// 二维码图片流
/// </summary>
/// <param name="userAvater">头像</param>
/// <param name="url">地址</param>
/// <param name="storeName">姓名</param>
/// <param name="templateImg">海报背景图</param>
/// <returns></returns>
public Stream GetRecommendQrCodeText(string userAvater, string url, string storeName)
{
if (string.IsNullOrWhiteSpace(userAvater) || userAvater == "null")
userAvater = "/Image/personalImg.png";
return GetRecommendQrCode(userAvater, url, storeName, (templateImage) =>
{
//获取头像
byte[] _avaterImageBytes = GetOtherImgThum(userAvater, 120, 120, false);
//获取二维码
byte[] _codeImageBytes = GetQrCode(url, 190, 190, 0);
//把头像画进画布
templateImage = PaintImage(templateImage, _avaterImageBytes, 76, 409);
//把二维码画进画布
templateImage = PaintImage(templateImage, _codeImageBytes, 370, 409);
templateImage = WriteTextInImage(templateImage,"一起研究海报是怎样生成的", "微软雅黑", 28, 76, 76, 76, 110, 100);
templateImage = WriteTextInImage(templateImage, storeName+"邀请你一起关注右右下方的二维码", "微软雅黑", 23, 76, 76, 76, 120, 209);
templateImage = WriteTextInImage(templateImage, "用手机扫描识别", "微软雅黑", 23, 76, 76, 76, 195, 409);
return templateImage;
});
}
/// <summary>
/// 获取推广二维码图片流
/// </summary>
/// <param name="userAvater"></param>
/// <param name="userName"></param>
/// <param name="url"></param>
/// <param name="storeName"></param>
/// <param name="fuc"></param>
/// <returns></returns>
public Stream GetRecommendQrCode(string userAvater, string url, string storeName,Func<Image, Image> fuc = null)
{
System.Drawing.Image templateImage = System.Drawing.Image.FromStream(new System.IO.MemoryStream(TemplateImageBytes));
if (fuc != null)
{
//写入文字或图片写入到背景图上
templateImage = fuc(templateImage);
}
var ms = new MemoryStream();
templateImage.Save(ms, ImageFormat.Png);
templateImage.Dispose();
ms.Position = 0;
return ms;
}
/// <summary>
/// 获取外域图片,并生产缩略图
/// </summary>
/// <param name="url">图片路径</param>
/// <param name="width">宽度</param>
/// <param name="height">高度</param>
/// <param name="isImageAvater">是否变成圆形 传true图片变成圆形</param>
/// <returns></returns>
private static byte[] GetOtherImgThum(string url, int width = 250, int height = 250, bool isImageAvater = true)
{
if (!url.ToLower().StartsWith("http://") && !url.ToLower().StartsWith("https://"))
{
//获取画布
string templatePath = GetMapPath(url);
return System.IO.File.ReadAllBytes(templatePath);
}
System.Net.WebClient wc = new System.Net.WebClient();
byte[] bs = wc.DownloadData(url);
System.Drawing.Image img = System.Drawing.Image.FromStream(new System.IO.MemoryStream(bs));
int srcWidth = img.Width;
int srcHeight = img.Height;
System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(width, height);
System.Drawing.Graphics gr = System.Drawing.Graphics.FromImage(bmp);
try
{
gr.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
gr.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
gr.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;
System.Drawing.Rectangle rectDestination = new System.Drawing.Rectangle(0, 0, width, height);
gr.DrawImage(img, rectDestination, 0, 0, srcWidth, srcHeight, System.Drawing.GraphicsUnit.Pixel);
if (!isImageAvater)
{
int r = Math.Min(bmp.Width, bmp.Height) / 2;
PointF c = new PointF(bmp.Width / 2.0F, bmp.Height / 2.0F);
for (int h = 0; h < bmp.Height; h++)
for (int w = 0; w < bmp.Width; w++)
if ((int)Math.Pow(r, 2) < ((int)Math.Pow(w * 1.0 - c.X, 2) + (int)Math.Pow(h * 1.0 - c.Y, 2)))
{
bmp.SetPixel(w, h, Color.Transparent);
}
}
using (System.IO.MemoryStream ms = new System.IO.MemoryStream())
{
bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
return ms.ToArray();
}
}
catch (Exception e)
{
throw e;
}
finally
{
img.Dispose();
gr.Dispose();
bmp.Dispose();
}
}
/// <summary>
/// 把图片画进画布里
/// </summary>
/// <param name="templateImage"></param>
/// <param name="_markByte"></param>
/// <param name="posX"></param>
/// <param name="posY"></param>
/// <returns></returns>
private Image PaintImage(System.Drawing.Image templateImage, byte[] _markByte, int posX, int posY)
{
System.Drawing.Image avaterImage = System.Drawing.Image.FromStream(new System.IO.MemoryStream(_markByte));
System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(templateImage);
//设置高质量插值法
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
//设置高质量,低速度呈现平滑程度
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
System.Drawing.Imaging.ImageAttributes imageAttributes = new System.Drawing.Imaging.ImageAttributes();
try
{
float[][] colorMatrixElements = {
new float[] {1.0f, 0.0f, 0.0f, 0.0f, 0.0f},
new float[] {0.0f, 1.0f, 0.0f, 0.0f, 0.0f},
new float[] {0.0f, 0.0f, 1.0f, 0.0f, 0.0f},
new float[] {0.0f, 0.0f, 0.0f, 1.0f, 0.0f},
new float[] {0.0f, 0.0f, 0.0f, 0.0f, 1.0f}
};
System.Drawing.Imaging.ColorMatrix colorMatrix = new System.Drawing.Imaging.ColorMatrix(colorMatrixElements);
imageAttributes.SetColorMatrix(colorMatrix, System.Drawing.Imaging.ColorMatrixFlag.Default, System.Drawing.Imaging.ColorAdjustType.Bitmap);
g.DrawImage(avaterImage, new System.Drawing.Rectangle(posX, posY, avaterImage.Width, avaterImage.Height), 0, 0, avaterImage.Width, avaterImage.Height, System.Drawing.GraphicsUnit.Pixel, imageAttributes);
return templateImage;
}
catch (Exception e)
{
throw e;
}
finally
{
avaterImage.Dispose();
g.Dispose();
imageAttributes.Dispose();
}
}
/// <summary>
/// 把文字画进画布
/// </summary>
/// <param name="templateImage"></param>
/// <param name="text"></param>
/// <param name="fontname"></param>
/// <param name="fontsize"></param>
/// <param name="red"></param>
/// <param name="green"></param>
/// <param name="blue"></param>
/// <param name="posX"></param>
/// <param name="posY"></param>
/// <returns></returns>
private Image WriteTextInImage(System.Drawing.Image templateImage, string text, string fontname, int fontsize, int red, int green, int blue, int posX, int posY)
{
System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(templateImage);
//设置高质量插值法
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
//设置高质量,低速度呈现平滑程度
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
try
{
System.Drawing.Font drawFont = new System.Drawing.Font(fontname, fontsize, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Pixel);
System.Drawing.SizeF crSize;
crSize = g.MeasureString(text, drawFont);
g.DrawString(text, drawFont, new System.Drawing.SolidBrush(System.Drawing.Color.FromArgb(red, green, blue)), posX, posY);
return templateImage;
}
catch (Exception e)
{
throw e;
}
finally
{
g.Dispose();
}
}
/// <summary>
/// 生成二维码
/// </summary>
/// <param name="qrValue">二维码内容</param>
/// <param name="height">二维码高度,默认250</param>
/// <param name="width">二维码宽度,默认250</param>
/// <param name="margin">二维码边距,默认0</param>
/// <param name="logo">logo图片 有就加没有就算了</param>
/// <returns></returns>
public static byte[] GetQrCode(string qrValue = "https://www.baidu.com", int height = 250, int width = 250, int margin = 0, byte[] logo = null)
{
// 1.设置QR二维码的规格
var qrEncodeOption = new ZXing.QrCode.QrCodeEncodingOptions();
qrEncodeOption.CharacterSet = "UTF-8"; // 设置编码格式,否则读取'中文'乱码
qrEncodeOption.Height = height;
qrEncodeOption.Width = width;
qrEncodeOption.Margin = margin; // 设置周围空白边距
// 2.生成条形码图片并保存
var wr = new ZXing.BarcodeWriter();
wr.Format = ZXing.BarcodeFormat.QR_CODE; // 二维码
wr.Options = qrEncodeOption;
using (Bitmap img = wr.Write(qrValue))
{
if (logo != null)
{
// 3.在二维码的Bitmap对象上绘制logo图片
var logoImg = System.Drawing.Image.FromStream(new System.IO.MemoryStream(logo)) as Bitmap;
//var logoImg = Bitmap.FromFile(logo) as Bitmap;
var g = Graphics.FromImage(img);
var logoRec = new Rectangle(); // 设置logo图片的大小和绘制位置
logoRec.Width = img.Width / 6;
logoRec.Height = img.Height / 6;
logoRec.X = img.Width / 2 - logoRec.Width / 2; // 中心点
logoRec.Y = img.Height / 2 - logoRec.Height / 2;
g.DrawImage(logoImg, logoRec);
}
using (var stream = new System.IO.MemoryStream())
{
img.Save(stream, System.Drawing.Imaging.ImageFormat.Gif);
return stream.ToArray();
}
}
}
//锁对象
private static object lockHelper = new object();
private static byte[] templateImageBytes;
private byte[] TemplateImageBytes
{
get
{
if (templateImageBytes == null)
{
lock (lockHelper)
{
if (templateImageBytes == null)
{
string templateImg = "/Image/tem.jpg";
//获取画布
string templatePath = GetMapPath(templateImg);
templateImageBytes = System.IO.File.ReadAllBytes(templatePath);
}
}
}
return templateImageBytes;
}
}
/// <summary>
/// 获取画布
/// </summary>
/// <param name="path"></param>
/// <returns></returns>
public static string GetMapPath(string path)
{
if (path.ToLower().StartsWith("http://"))
{
return path;
}
if (HttpContext.Current != null)
{
return HttpContext.Current.Server.MapPath(path);
}
else //非web程序引用
{
path = AppDomain.CurrentDomain.BaseDirectory + path.Replace("/", "\\");
return path;
}
}
}
看效果
虽然难看了一点,x轴、y轴都是可以 自己调的,还有背景图可以自己换
百度网盘链接:
链接:https://pan.baidu.com/s/1vkvZK7JemlcoM4rqeGGYNg
提取码:7112