zoukankan      html  css  js  c++  java
  • 使用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             });

    效果图:

  • 相关阅读:
    算法>分支限界 小强斋
    C# DataGridView 的 CellValueChanged 与修改数据没保存的情况
    Windows8使用虚拟磁盘vhdx功能来为容量较大的文件夹扩容
    DataSet / DataTable 对 Access 数据库进行更改后,无法获取自动编号(自增)列的新值
    使用Windows Server 2012配置更新服务Update Service,以及客户端的配置
    在Windows 8中找回开始菜单
    DataSet / BindingSource / DataGridView / BindingNavigator 的关系与绑定、更新顺序
    Windows8 的搜狗输入法的快捷键推荐设置方法
    如果要使用DataAdapter来修改DataSet的子集时,请尽量对父级做修改。
    about PostgreSQL
  • 原文地址:https://www.cnblogs.com/peterzhang123/p/13441579.html
Copyright © 2011-2022 走看看