C#使用Graphics合成二维码和头像的分享图(小程序分享、App分享)-C/S开发框架
作者:csframework|C/S框架网  发布日期:2021/12/30 19:01:55

C#使用Graphics合成二维码和头像的分享图(小程序分享、App分享)-C/S开发框架

适用于微信小程序分享图、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格式

         private static ImageCodecInfo GetEncoder(ImageFormat format)
         {
 
             ImageCodecInfo[] codecs = ImageCodecInfo.GetImageDecoders();
 
             foreach (ImageCodecInfo codec in codecs)
             {
                 if (codec.FormatID == format.Guid)
                 {
                     return codec;
                 }
             }
             return null;
         }

ReduceImage 方法可以缩放图片大小

         /// <summary>
         /// 缩小/放大图片  
         /// </summary>
         /// <param name="url">图片网络地址</param>
         /// <param name="toWidth">缩小/放大宽度</param>
         /// <param name="toHeight">缩小/放大高度</param>
         /// <returns></returns>
         private static Image ReduceImage(string url, int toWidth, int toHeight, string param = null)
         {
             try
             {
                 Stream responseStream = null;
                 if (param != null)   //post请求
                 {
                     var intResult = HttpHelper.HttpClientPost(url, param, out responseStream);
                 }
                 else
                 {
                     WebRequest request = WebRequest.Create(url);
                     WebResponse response = request.GetResponse();
                     responseStream = response.GetResponseStream();
                 }
                 if (responseStream == null)
                 {
                     return null;
                 }
 
                 Image originalImage = Image.FromStream(responseStream);
                 if (toWidth <= 0 && toHeight <= 0)  //返回原图
                 {
                     return originalImage;
                 }
                 else if (toWidth > 0 && toHeight > 0)  ////给了宽*高 如果原始小,则返回原图
                 {
                     if (originalImage.Width < toWidth && originalImage.Height < toHeight)
                         return originalImage;
                 }
                 else if (toWidth <= 0 && toHeight > 0)  //给了高,根据高计算宽,得出正方形图片
                 {
                     if (originalImage.Height < toHeight)
                         return originalImage;
                     toWidth = originalImage.Width * toHeight / originalImage.Height;
                 }
                 else if (toHeight <= 0 && toWidth > 0)  //给了宽,根据宽计算高,得出正方形图片
                 {
                     if (originalImage.Width < toWidth)
                         return originalImage;
                     toHeight = originalImage.Height * toWidth / originalImage.Width;
                 }
                 Image toBitmap = new Bitmap(toWidth, toHeight);   //定义一个指定大小的画布背景
                 using (Graphics g = Graphics.FromImage(toBitmap))   //定义画图工具,使用画图工具加载画布背景,开始在画布上作图
                 {
                     //图片缩放时使用
                     g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighSpeed;  //高速度、低质量
                     g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; //图像缩放质量
                     //生成图片时使用
                     g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;  //图片呈现质量,即消除锯齿
                     g.Clear(Color.Transparent);  //清除背景色,并设置颜色为透明 Color.Transparent
                     g.DrawImage(originalImage,
                                 new Rectangle(0, 0, toWidth, toHeight),
                                 new Rectangle(0, 0, originalImage.Width, originalImage.Height),
                                 GraphicsUnit.Pixel);
                     originalImage.Dispose();
                     responseStream.Dispose();
                     g.Dispose();
                     return toBitmap;
                 }
             }
             catch (Exception ex)
             {
                 throw;
             }
         }

CutEllipse方法用来裁剪头像

         /// <summary>
         /// 画圆形头像
         /// </summary>
         /// <param name="img">待裁剪的图片</param>
         /// <param name="size">裁剪大小</param>
         /// <returns></returns>
         private static Image CutEllipse(Image img, Size size)
         {
             try
             {
                 var rec = new Rectangle(0, 0, size.Width, size.Height); //声明位置和大小
                 Bitmap bitmap = new Bitmap(size.Width, size.Height);  //声明画布并指定大小
                 Pen p = new Pen(Color.Transparent);  //声明透明色画笔
                 using (Graphics g = Graphics.FromImage(bitmap))
                 {
                     using (TextureBrush br = new TextureBrush(img, rec))  //声明画刷
                     {
                         g.SmoothingMode = SmoothingMode.HighQuality;  //使绘图质量最高,即消除锯齿
                         g.InterpolationMode = InterpolationMode.HighQualityBicubic;
                         g.CompositingQuality = CompositingQuality.HighQuality;
 
                         g.FillEllipse(br, rec);  //根据指定大小和位置填充圆形
                         g.DrawEllipse(p, rec);   //画圆形图
                         br.Dispose();
                     }
                     g.Dispose();
                 }
                 return bitmap;
             }
             catch (Exception ex)
             {
                 throw;
             }
         }

接下来开始测试:

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

         /// <summary>
         /// 后端以二进制格式输出到页面
         /// </summary>
         /// <returns></returns>
         [HttpPost]
         public ActionResult DrawImages()
         {
             try
             {
                 string pathparam = "123";
                 byte[] buffer = null;
                 DrawShareImage(pathparam, out buffer);
 
                 Response.ClearContent();
                 Response.ContentType = "image/jpeg";
                 Response.BinaryWrite(buffer);
             }
             catch (Exception)
             {
                 throw;
             }
             return View();
         }

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

             //方式1
             var xhr = new XMLHttpRequest();
             xhr.open('POST', apihost + '/Test/DrawImages', true);
             xhr.responseType = 'blob';  
             xhr.setRequestHeader("client_type", "DESKTOP_WEB");
             xhr.onload = function () {
                 if (this.status === 200) {
                     var blob = this.response;
                     var imageUrl = window.URL.createObjectURL(blob);;
                     $("#showimg").attr('src', imageUrl);
                 }
             }
             xhr.send();
 
 
             //方式2
             var xhr = new XMLHttpRequest();
             xhr.open('POST', apihost + '/Test/DrawImages', true);
             xhr.responseType = 'arraybuffer';  
             xhr.setRequestHeader("client_type", "DESKTOP_WEB");
             xhr.onload = function () {
                 if (this.status === 200) {
                     var blob = this.response;
                     let bytes = new Uint8Array(blob);
                     let data = "";
                     let len = bytes.byteLength;
                     for (let i = 0; i < len; i++) {
                         data += String.fromCharCode(bytes[i]);
                     }
                     var imageUrl = "data:image/jpeg;base64," + window.btoa(data);
                     $("#showimg").attr('src', imageUrl);
                 }
             }
             xhr.send();

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

         /// <summary>
         /// 后端以文件流格式输出到页面
         /// </summary>
         /// <returns></returns>
         [HttpPost]
         public FileResult DrawImages()
         {
             try
             {
                 string pathparam = "123";
                 byte[] buffer = null;
                 DrawShareImage(pathparam, out buffer);
 
                 //Response.ClearContent();
                 //Response.ContentType = "image/jpeg";
                 //Response.BinaryWrite(buffer);
 
                 return new FileContentResult(buffer, "image/jpeg");
             }
             catch (Exception)
             {
                 throw;
             }
         }

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

         /// <summary>
         /// 后端以Base64格式输出到页面
         /// </summary>
         /// <returns></returns>
         [HttpPost]
         public string DrawImages()
         {
             try
             {
                 string pathparam = "123";
                 byte[] buffer = null;
                 DrawShareImage(pathparam, out buffer);
                 return Convert.ToBase64String(buffer);
             }
             catch (Exception ex)
             {
                 throw;
             }
         }

前端请求Base64格式图片

             //方法1
             var xhr = new XMLHttpRequest();
             xhr.open('POST', apihost + '/Test/DrawImages', true);
             xhr.responseType = 'text';  //"" | "arraybuffer" | "blob" | "document" | "json" | "text"
             xhr.setRequestHeader("client_type", "DESKTOP_WEB");
             xhr.onload = function () {
                 if (this.status === 200) {
                     var content = this.response;
                     var imageUrl = "data:image/jepg;base64," + content;
                     $("#showimg").attr('src', imageUrl);
                 }
             }
             xhr.send();
 
 
             //方法2
             $.ajax({
                 type: "POST",//方法类型
                 dataType: "text", //服务器返回的数据类型
                 url: apihost + "/Test/DrawImages",//url
                 data: {},   //jQuery的serialize()方法通过序列化表单值
                 success: function (result) {
                     var imageUrl = "data:image/jepg;base64," + result;
                     $("#showimg").attr('src', imageUrl);
                 },
                 error: function (s) {
                     alert("异常!");
                 }
             });

效果图:

C#使用Graphics合成二维码和头像的分享图(小程序分享、App分享)-C/S开发框架

C#使用Graphics合成二维码和头像的分享图(小程序分享、App分享)-C/S开发框架

CSCODE.NETC/S开发框架-C/S框架网专注.NET技术、C/S架构快速开发框架软件

上一篇 下一篇