使用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,tifflong 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             try11             {12                 Stream responseStream = null;13                 if (param != null)   //post请求14                 {15                     var intResult = HttpHelper.HttpClientPost(url, param, out responseStream);16                 }17                 else18                 {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.Transparent59                     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             try10             {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             //方式217             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             //方法217             $.ajax({18                 type: "POST",//方法类型19                 dataType: "text", //服务器返回的数据类型20                 url: apihost + "/Test/DrawImages",//url21                 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             });

效果图:

(0)

相关推荐