详细QRCode生成二维码和下载实现案例
程序员文章站
2022-03-13 17:14:00
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... ......
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 }