使用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格式ajax

 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 方法能夠縮放圖片大小json

 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的方式請求,結果發現數據格式不支持,遂改用如下方式接收api

 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             });

效果圖:

相關文章
相關標籤/搜索