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 }