使用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)