使用Graphics合成带二维码和头像的分享图(小程序分享、App分享)

适用于微信小程序分享图、app分享图

//分享的海报背景图片 使用本地图片文件  
string path = Server.MapPath("/Content/images/backimg.jpg");
Image imgSrc = Image.FromFile(path);   //将文件加载成图片格式

//二维码图片文件  使用远程图片文件  
var qr_url="http://xxxxxx:8001/Images/qrimg.jpg";
Image qrCodeImage= ReduceImage(qr_url, 122, 122);

//头像文件  使用远程图片文件  
var headurl="http://xxxxxx:8001/Images/header.jpg";
Image headImage=  ReduceImage(headurl, 59, 59);

//开始合成图片   声明画图工具
using (Graphics g = Graphics.FromImage(imgSrc))  
{
      //画推广二维码 声明起始坐标点
      //从x轴30像素处、y轴的40像素处开始画
      int qr_x = 30,qr_y = 40;  

       //指定二维码在合成图上显示的坐标和区域大小
       Rectangle destRect = new Rectangle(qr_x, qr_y, qrCodeImage.Width, qrCodeImage.Height);
        //在destRect声明的区域内,开始绘制二维码
       Rectangle srcRect = new Rectangle(0, 0, qrCodeImage.Width, qrCodeImage.Height);
        //开始绘制  GraphicsUnit.Pixel 表示以像素为单位
       g.DrawImage(qrCodeImage, destRect, srcRect, GraphicsUnit.Pixel);

        //画头像 裁剪头像(圆形)
       Image header = CutEllipse(titleImage, new Size(59, 59));   
       int w = header.Width, h = header.Height;  //图片宽高
       int x = 24, y = 982;   //图片坐标 
       g.DrawImage(header,
                        new Rectangle(x, y, w, h),
                        new Rectangle(0, 0, w, h),
                        GraphicsUnit.Pixel);

        //画昵称  思源黑体 CN 常规  字体大小18  粗体
        Font font = new Font("Source Han Sans CN Regular", 18, FontStyle.Bold, GraphicsUnit.Pixel);
        Color fontColor = (Color)new ColorConverter().ConvertFromString("#999999");
        g.DrawString("张三", font, new SolidBrush(fontColor), 100, 990);  //坐标点 x=100  y=990

        //画其他文本  思源黑体 CN 常规
        var othertext = "邀请您看直播";
        g.DrawString(othertext, font, new SolidBrush(fontColor), 101, 1014);  //坐标点 x=100  y=990

        header.Dispose();
        g.Dispose();
}

//获取系统编码类型数组,包含了jpeg,bmp,png,gif,tiff
long quality = 80L; //图像质量 1 - 100的范围  图片的质量决定了生成图片后的文件大小
ImageCodecInfo[] icis = ImageCodecInfo.GetImageEncoders();
ImageCodecInfo ici = GetEncoder(ImageFormat.Jpeg);
EncoderParameters ep = new EncoderParameters(1);
ep.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, quality);

//将图片转换成二进制流
MemoryStream ms = new MemoryStream();//读取字节流
imgSrc.Save(ms, ici, ep);
var buffer = ms.GetBuffer();  //图片流

ms.Dispose();
imgSrc.Dispose();
qrCodeImage.Dispose();
headImage.Dispose();
ep.Dispose();

GetEncoder 方法用于返回图片的格式,这里设置的为jpeg格式

 1         private static ImageCodecInfo GetEncoder(ImageFormat format)
 2         {
 3 
 4             ImageCodecInfo[] codecs = ImageCodecInfo.GetImageDecoders();
 5 
 6             foreach (ImageCodecInfo codec in codecs)
 7             {
 8                 if (codec.FormatID == format.Guid)
 9                 {
10                     return codec;
11                 }
12             }
13             return null;
14         }

ReduceImage 方法可以缩放图片大小

 1         /// <summary>
 2         /// 缩小/放大图片  
 3         /// </summary>
 4         /// <param name="url">图片网络地址</param>
 5         /// <param name="toWidth">缩小/放大宽度</param>
 6         /// <param name="toHeight">缩小/放大高度</param>
 7         /// <returns></returns>
 8         private static Image ReduceImage(string url, int toWidth, int toHeight, string param = null)
 9         {
10             try
11             {
12                 Stream responseStream = null;
13                 if (param != null)   //post请求
14                 {
15                     var intResult = HttpHelper.HttpClientPost(url, param, out responseStream);
16                 }
17                 else
18                 {
19                     WebRequest request = WebRequest.Create(url);
20                     WebResponse response = request.GetResponse();
21                     responseStream = response.GetResponseStream();
22                 }
23                 if (responseStream == null)
24                 {
25                     return null;
26                 }
27 
28                 Image originalImage = Image.FromStream(responseStream);
29                 if (toWidth <= 0 && toHeight <= 0)  //返回原图
30                 {
31                     return originalImage;
32                 }
33                 else if (toWidth > 0 && toHeight > 0)  ////给了宽*高 如果原始小,则返回原图
34                 {
35                     if (originalImage.Width < toWidth && originalImage.Height < toHeight)
36                         return originalImage;
37                 }
38                 else if (toWidth <= 0 && toHeight > 0)  //给了高,根据高计算宽,得出正方形图片
39                 {
40                     if (originalImage.Height < toHeight)
41                         return originalImage;
42                     toWidth = originalImage.Width * toHeight / originalImage.Height;
43                 }
44                 else if (toHeight <= 0 && toWidth > 0)  //给了宽,根据宽计算高,得出正方形图片
45                 {
46                     if (originalImage.Width < toWidth)
47                         return originalImage;
48                     toHeight = originalImage.Height * toWidth / originalImage.Width;
49                 }
50                 Image toBitmap = new Bitmap(toWidth, toHeight);   //定义一个指定大小的画布背景
51                 using (Graphics g = Graphics.FromImage(toBitmap))   //定义画图工具,使用画图工具加载画布背景,开始在画布上作图
52                 {
53                     //图片缩放时使用
54                     g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighSpeed;  //高速度、低质量
55                     g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; //图像缩放质量
56                     //生成图片时使用
57                     g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;  //图片呈现质量,即消除锯齿
58                     g.Clear(Color.Transparent);  //清除背景色,并设置颜色为透明 Color.Transparent
59                     g.DrawImage(originalImage,
60                                 new Rectangle(0, 0, toWidth, toHeight),
61                                 new Rectangle(0, 0, originalImage.Width, originalImage.Height),
62                                 GraphicsUnit.Pixel);
63                     originalImage.Dispose();
64                     responseStream.Dispose();
65                     g.Dispose();
66                     return toBitmap;
67                 }
68             }
69             catch (Exception ex)
70             {
71                 throw;
72             }
73         }

CutEllipse方法用来裁剪头像

 1         /// <summary>
 2         /// 画圆形头像
 3         /// </summary>
 4         /// <param name="img">待裁剪的图片</param>
 5         /// <param name="size">裁剪大小</param>
 6         /// <returns></returns>
 7         private static Image CutEllipse(Image img, Size size)
 8         {
 9             try
10             {
11                 var rec = new Rectangle(0, 0, size.Width, size.Height); //声明位置和大小
12                 Bitmap bitmap = new Bitmap(size.Width, size.Height);  //声明画布并指定大小
13                 Pen p = new Pen(Color.Transparent);  //声明透明色画笔
14                 using (Graphics g = Graphics.FromImage(bitmap))
15                 {
16                     using (TextureBrush br = new TextureBrush(img, rec))  //声明画刷
17                     {
18                         g.SmoothingMode = SmoothingMode.HighQuality;  //使绘图质量最高,即消除锯齿
19                         g.InterpolationMode = InterpolationMode.HighQualityBicubic;
20                         g.CompositingQuality = CompositingQuality.HighQuality;
21 
22                         g.FillEllipse(br, rec);  //根据指定大小和位置填充圆形
23                         g.DrawEllipse(p, rec);   //画圆形图
24                         br.Dispose();
25                     }
26                     g.Dispose();
27                 }
28                 return bitmap;
29             }
30             catch (Exception ex)
31             {
32                 throw;
33             }
34         }

接下来开始测试:

后端返回图片方式1: 服务端以 Response.BinaryWrite(buffer) 格式输出到前端

 1         /// <summary>
 2         /// 后端以二进制格式输出到页面
 3         /// </summary>
 4         /// <returns></returns>
 5         [HttpPost]
 6         public ActionResult DrawImages()
 7         {
 8             try
 9             {
10                 string pathparam = "123";
11                 byte[] buffer = null;
12                 DrawShareImage(pathparam, out buffer);
13 
14                 Response.ClearContent();
15                 Response.ContentType = "image/jpeg";
16                 Response.BinaryWrite(buffer);
17             }
18             catch (Exception)
19             {
20                 throw;
21             }
22             return View();
23         }

前端接收方式:原本想使用Ajax的方式请求,结果发现数据格式不支持,遂改用以下方式接收

 1             //方式1
 2             var xhr = new XMLHttpRequest();
 3             xhr.open('POST', apihost + '/Test/DrawImages', true);
 4             xhr.responseType = 'blob';  
 5             xhr.setRequestHeader("client_type", "DESKTOP_WEB");
 6             xhr.onload = function () {
 7                 if (this.status === 200) {
 8                     var blob = this.response;
 9                     var imageUrl = window.URL.createObjectURL(blob);;
10                     $("#showimg").attr('src', imageUrl);
11                 }
12             }
13             xhr.send();
14 
15 
16             //方式2
17             var xhr = new XMLHttpRequest();
18             xhr.open('POST', apihost + '/Test/DrawImages', true);
19             xhr.responseType = 'arraybuffer';  
20             xhr.setRequestHeader("client_type", "DESKTOP_WEB");
21             xhr.onload = function () {
22                 if (this.status === 200) {
23                     var blob = this.response;
24                     let bytes = new Uint8Array(blob);
25                     let data = "";
26                     let len = bytes.byteLength;
27                     for (let i = 0; i < len; i++) {
28                         data += String.fromCharCode(bytes[i]);
29                     }
30                     var imageUrl = "data:image/jpeg;base64," + window.btoa(data);
31                     $("#showimg").attr('src', imageUrl);
32                 }
33             }
34             xhr.send();

后端返回图片方式2: 服务端以 FileContentResult(buffer) 格式输出到前端,前端请求方式同上

 1         /// <summary>
 2         /// 后端以文件流格式输出到页面
 3         /// </summary>
 4         /// <returns></returns>
 5         [HttpPost]
 6         public FileResult DrawImages()
 7         {
 8             try
 9             {
10                 string pathparam = "123";
11                 byte[] buffer = null;
12                 DrawShareImage(pathparam, out buffer);
13 
14                 //Response.ClearContent();
15                 //Response.ContentType = "image/jpeg";
16                 //Response.BinaryWrite(buffer);
17 
18                 return new FileContentResult(buffer, "image/jpeg");
19             }
20             catch (Exception)
21             {
22                 throw;
23             }
24         }

后端返回图片方式3: 服务端以 Base64字符串格式输出到前端,前端可以使用Ajax方式请求

 1         /// <summary>
 2         /// 后端以Base64格式输出到页面
 3         /// </summary>
 4         /// <returns></returns>
 5         [HttpPost]
 6         public string DrawImages()
 7         {
 8             try
 9             {
10                 string pathparam = "123";
11                 byte[] buffer = null;
12                 DrawShareImage(pathparam, out buffer);
13                 return Convert.ToBase64String(buffer);
14             }
15             catch (Exception ex)
16             {
17                 throw;
18             }
19         }

前端请求Base64格式图片

 1             //方法1
 2             var xhr = new XMLHttpRequest();
 3             xhr.open('POST', apihost + '/Test/DrawImages', true);
 4             xhr.responseType = 'text';  //"" | "arraybuffer" | "blob" | "document" | "json" | "text"
 5             xhr.setRequestHeader("client_type", "DESKTOP_WEB");
 6             xhr.onload = function () {
 7                 if (this.status === 200) {
 8                     var content = this.response;
 9                     var imageUrl = "data:image/jepg;base64," + content;
10                     $("#showimg").attr('src', imageUrl);
11                 }
12             }
13             xhr.send();
14 
15 
16             //方法2
17             $.ajax({
18                 type: "POST",//方法类型
19                 dataType: "text", //服务器返回的数据类型
20                 url: apihost + "/Test/DrawImages",//url
21                 data: {},   //jQuery的serialize()方法通过序列化表单值
22                 success: function (result) {
23                     var imageUrl = "data:image/jepg;base64," + result;
24                     $("#showimg").attr('src', imageUrl);
25                 },
26                 error: function (s) {
27                     alert("异常!");
28                 }
29             });

效果图:

原文地址:https://www.cnblogs.com/peterzhang123/p/13441579.html