1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Web;
5 using ThoughtWorks.QRCode.Codec;
6 using System.Drawing;
7 using System.Drawing.Imaging;
8 using Game.Utils;
9 using System.Drawing.Drawing2D;
10 using Game.Facade;
11 using System.Net;
12 using System.IO;
13
14 namespace Game.Web.WS
15 {
16 /// <summary>
17 /// QRCode 的摘要说明
18 /// </summary>
19 public class QRCode : IHttpHandler
20 {
21
22 public void ProcessRequest(HttpContext context)
23 {
24 GetQRCode(context);
25 }
26
27 /// <summary>
28 /// 绘制二维码
29 /// </summary>
30 /// <param name="context"></param>
31 private void GetQRCode(HttpContext context)
32 {
33 string encodeData = GameRequest.GetQueryString("qt");
34 string icoURL = GameRequest.GetQueryString("qm");
35 int width = GameRequest.GetQueryInt("qs", 0);
36 if (encodeData != string.Empty)
37 {
38 calQrcode(encodeData, icoURL, width, context);
39 }
40 }
41
42 /// <summary>
43 /// 按照指定的大小绘制二维码
44 /// </summary>
45 /// <param name="sData"></param>
46 /// <param name="width"></param>
47 /// <returns></returns>
48 private void calQrcode(string sData, string icoURL, int size, HttpContext context)
49 {
50 //二维码版本,大小获取
51 Color qrCodeBackgroundColor = Color.White;
52 Color qrCodeForegroundColor = Color.Black;
53 int length = System.Text.Encoding.UTF8.GetBytes(sData).Length;
54
55 //生成二维码数据
56 QRCodeEncoder qrCodeEncoder = new QRCodeEncoder();
57 qrCodeEncoder.QRCodeEncodeMode = QRCodeEncoder.ENCODE_MODE.BYTE;
58 qrCodeEncoder.QRCodeErrorCorrect = QRCodeEncoder.ERROR_CORRECTION.M;//使用M纠错级别
59 qrCodeEncoder.QRCodeVersion = 0;
60 var encodedData = qrCodeEncoder.Encode(sData, System.Text.Encoding.UTF8);
61
62 //绘制图片
63 int x = 0, y = 0;
64 int w = 0, h = 0;
65 // 二维码矩阵单边数据点数目
66 int count = encodedData.Length;
67 // 获取单个数据点边长
68 double sideLength = Convert.ToDouble(size) / count;
69 // 初始化背景色画笔
70 SolidBrush backcolor = new SolidBrush(qrCodeBackgroundColor);
71 // 初始化前景色画笔
72 SolidBrush forecolor = new SolidBrush(qrCodeForegroundColor);
73 // 定义画布
74 Bitmap image = new Bitmap(size, size);
75 // 获取GDI+绘图图画
76 Graphics graph = Graphics.FromImage(image);
77 // 先填充背景色
78 graph.FillRectangle(backcolor, 0, 0, size, size);
79
80 // 变量数据矩阵生成二维码
81 for (int row = 0; row < count; row++)
82 {
83 for (int col = 0; col < count; col++)
84 {
85 // 计算数据点矩阵起始坐标和宽高
86 x = Convert.ToInt32(Math.Round(col * sideLength));
87 y = Convert.ToInt32(Math.Round(row * sideLength));
88 w = Convert.ToInt32(Math.Ceiling((col + 1) * sideLength) - Math.Floor(col * sideLength));
89 h = Convert.ToInt32(Math.Ceiling((row + 1) * sideLength) - Math.Floor(row * sideLength));
90
91 // 绘制数据矩阵
92 graph.FillRectangle(encodedData[col][row] ? forecolor : backcolor, x, y, w, h);
93 }
94 }
95
96 //添加LOGO
97 string path = context.Server.MapPath("/favicon.ico");
98 Bitmap logoImage = null;
99 FileInfo fileInfo = new FileInfo(path);
100 if (fileInfo.Exists)
101 {
102 logoImage = new Bitmap(path);
103 }
104 if (icoURL != "")
105 {
106 HttpWebRequest webRequest = (HttpWebRequest)HttpWebRequest.Create(icoURL);
107 try
108 {
109 HttpWebResponse webReponse = (HttpWebResponse)webRequest.GetResponse();
110 if (webReponse.StatusCode == HttpStatusCode.OK)
111 {
112 using (Stream stream = webReponse.GetResponseStream())
113 {
114 Image img = Image.FromStream(stream);
115 logoImage = new Bitmap(img);
116 img.Dispose();
117 }
118 }
119 }
120 catch { }
121 }
122 if (logoImage != null)
123 {
124 image = CoverImage(image, logoImage, graph);
125 logoImage.Dispose();
126 }
127 //输出
128 System.IO.MemoryStream ms = new System.IO.MemoryStream();
129 image.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
130 context.Response.ClearContent();
131 context.Response.ContentType = "image/png";
132 context.Response.AddHeader("Content-Disposition", "attachment; filename=" + HttpUtility.UrlEncode("QRCodeImg.png", System.Text.Encoding.UTF8));
133 context.Response.BinaryWrite(ms.ToArray());
134 context.Response.Flush();
135 context.Response.End();
136 image.Dispose();
137 }
138
139 /// <summary>
140 /// 层叠图片
141 /// </summary>
142 /// <param name="original">原始图片(目前只支持正方形)</param>
143 /// <param name="image">层叠图片(目前只支持正方形)</param>
144 /// <returns>处理以后的图片</returns>
145 private Bitmap CoverImage(Bitmap original, Bitmap image, Graphics graph = null)
146 {
147 //缩放附加图片
148 int sideSLen = original.Width;
149 int sideTLen = sideSLen / 4;
150 image = ResizeImage(image, sideTLen, sideTLen);
151
152 // 获取GDI+绘图图画
153 graph = graph == null ? Graphics.FromImage(original) : graph;
154
155 // 将附加图片绘制到原始图中央
156 graph.DrawImage(image, (original.Width - sideTLen) / 2, (original.Height - sideTLen) / 2, sideTLen, sideTLen);
157
158 // 释放GDI+绘图图画内存
159 graph.Dispose();
160
161 // 返回处理结果
162 return original;
163 }
164
165 /// <summary>
166 /// 图片缩放
167 /// </summary>
168 /// <param name="bmp">原始Bitmap</param>
169 /// <param name="newW">新的宽度</param>
170 /// <param name="newH">新的高度</param>
171 /// <returns>处理以后的图片</returns>
172 private Bitmap ResizeImage(Bitmap original, int width, int height)
173 {
174 try
175 {
176 Bitmap image = new Bitmap(width, height);
177 Graphics graph = Graphics.FromImage(image);
178 // 插值算法的质量
179 graph.CompositingQuality = CompositingQuality.HighQuality;
180 graph.SmoothingMode = SmoothingMode.HighQuality;
181 graph.InterpolationMode = InterpolationMode.HighQualityBicubic;
182 graph.DrawImage(original, new Rectangle(0, 0, width, height),
183 new Rectangle(0, 0, original.Width, original.Height), GraphicsUnit.Pixel);
184 graph.Dispose();
185 return image;
186 }
187 catch
188 {
189 return null;
190 }
191 }
192
193 public bool IsReusable
194 {
195 get
196 {
197 return false;
198 }
199 }
200 }
201 }