c# 的二維碼 需借助插件ThoughtWorks
直接引用
using ThoughtWorks.QRCode.Codec;
using ThoughtWorks.QRCode.Codec.Data;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
//生成二維碼方法1
//text 二維碼的文本內容
//Counselor對象內含微信頭像等信息
public static string GetTwoCodeMetho(string text, bk_Counselor Counselor)
{
String data = text;
string url = "";
if (!string.IsNullOrEmpty(data))
{
//聲明QRCodeEncoder 其屬性在下面的詳細方法中有解釋
QRCodeEncoder qrCodeEncoder = new QRCodeEncoder();
qrCodeEncoder.QRCodeEncodeMode = QRCodeEncoder.ENCODE_MODE.BYTE;
qrCodeEncoder.QRCodeScale = 4;
qrCodeEncoder.QRCodeVersion = 8;
qrCodeEncoder.QRCodeErrorCorrect = QRCodeEncoder.ERROR_CORRECTION.M;
Image image = CreateQRCode(data, QRCodeEncoder.ENCODE_MODE.BYTE, QRCodeEncoder.ERROR_CORRECTION.M, 8, 4, 0, 5);
//System.Drawing.Image image = qrCodeEncoder.Encode(data);
System.IO.MemoryStream MStream = new System.IO.MemoryStream();
image.Save(MStream, System.Drawing.Imaging.ImageFormat.Png);
System.IO.MemoryStream MStream1 = new System.IO.MemoryStream();
System.Drawing.Image codeimg;
//有微信頭像地址
if (!string.IsNullOrEmpty(Counselor.CounselorImg))
{
System.Net.WebRequest webreq = System.Net.WebRequest.Create(Counselor.CounselorImg);
System.Net.WebResponse webres = webreq.GetResponse();
Stream stream = webres.GetResponseStream();
Image ImageWeixin;
ImageWeixin = Image.FromStream(stream);
stream.Close();
codeimg = CombinImage(image, ImageWeixin);
codeimg.Save(MStream1, System.Drawing.Imaging.ImageFormat.Png);
}
else
{
codeimg = image;
}
//保存圖片到本地
string PortraitApp = "~/FileLibs/CodeImg/";
if (!Directory.Exists(HttpContext.Current.Server.MapPath(PortraitApp)))
{
Directory.CreateDirectory(HttpContext.Current.Server.MapPath(PortraitApp));
}
string filename = Counselor.CounselorName + DateTime.Now.ToString("yyyymmddhhmmssfff").ToString() + ".png";
string filepath = HttpContext.Current.Server.MapPath(PortraitApp) + "\\" + filename;
System.IO.FileStream fs = new System.IO.FileStream(filepath, System.IO.FileMode.OpenOrCreate, System.IO.FileAccess.Write);
codeimg.Save(fs, System.Drawing.Imaging.ImageFormat.Png);
//由於項目前后台分離 需要指定生成二維碼后的url
string RetureFile = System.Configuration.ConfigurationManager.AppSettings["RetureFile"].ToString();
url = RetureFile.Replace("/FileLibs/File/", "/FileLibs/CodeImg/") + filename;
//HttpContext.Current.Response.ClearContent();
//HttpContext.Current.Response.ContentType = "image/png";
//HttpContext.Current.Response.BinaryWrite(MStream1.ToArray());//直接輸出圖片 測試用
//處理完釋放資源
//image.Dispose();
MStream.Dispose();
MStream1.Dispose();
}
return url;
//HttpContext.Current.Response.Flush();
//HttpContext.Current.Response.End();
}
測試 效果圖如下:
/// <summary>
/// 生成二維碼 本函數摘錄自網友的方法,后面重寫了一個
/// </summary>
/// <param name="Content">內容文本</param>
/// <param name="QRCodeEncodeMode">二維碼編碼方式</param>
/// <param name="QRCodeErrorCorrect">糾錯碼等級</param>
/// <param name="QRCodeVersion">二維碼版本號 0-40</param>
/// <param name="QRCodeScale">每個小方格的預設寬度(像素),正整數</param>
/// <param name="size">圖片尺寸(像素),0表示不設置</param>
/// <param name="border">圖片白邊(像素),當size大於0時有效</param>
/// <returns></returns>
public static System.Drawing.Image CreateQRCode(string Content, QRCodeEncoder.ENCODE_MODE QRCodeEncodeMode, QRCodeEncoder.ERROR_CORRECTION QRCodeErrorCorrect, int QRCodeVersion, int QRCodeScale, int size, int border)
{
QRCodeEncoder qrCodeEncoder = new QRCodeEncoder();
qrCodeEncoder.QRCodeEncodeMode = QRCodeEncodeMode;
qrCodeEncoder.QRCodeErrorCorrect = QRCodeErrorCorrect;
qrCodeEncoder.QRCodeScale = QRCodeScale;
qrCodeEncoder.QRCodeVersion = QRCodeVersion;
System.Drawing.Image image = qrCodeEncoder.Encode(Content);
#region 根據設定的目標圖片尺寸調整二維碼QRCodeScale設置,並添加邊框
if (size > 0)
{
//當設定目標圖片尺寸大於生成的尺寸時,逐步增大方格尺寸
#region 當設定目標圖片尺寸大於生成的尺寸時,逐步增大方格尺寸
while (image.Width < size)
{
qrCodeEncoder.QRCodeScale++;
System.Drawing.Image imageNew = qrCodeEncoder.Encode(Content);
if (imageNew.Width < size)
{
image = new System.Drawing.Bitmap(imageNew);
imageNew.Dispose();
imageNew = null;
}
else
{
qrCodeEncoder.QRCodeScale--; //新尺寸未采用,恢復最終使用的尺寸
imageNew.Dispose();
imageNew = null;
break;
}
}
#endregion
//當設定目標圖片尺寸小於生成的尺寸時,逐步減小方格尺寸
#region 當設定目標圖片尺寸小於生成的尺寸時,逐步減小方格尺寸
while (image.Width > size && qrCodeEncoder.QRCodeScale > 1)
{
qrCodeEncoder.QRCodeScale--;
System.Drawing.Image imageNew = qrCodeEncoder.Encode(Content);
image = new System.Drawing.Bitmap(imageNew);
imageNew.Dispose();
imageNew = null;
if (image.Width < size)
{
break;
}
}
#endregion
//如果目標尺寸大於生成的圖片尺寸,則為圖片增加白邊
#region 如果目標尺寸大於生成的圖片尺寸,則為圖片增加白邊
if (image.Width <= size)
{
//根據參數設置二維碼圖片白邊的最小寬度
#region 根據參數設置二維碼圖片白邊的最小寬度
if (border > 0)
{
while (image.Width <= size && size - image.Width < border * 2 && qrCodeEncoder.QRCodeScale > 1)
{
qrCodeEncoder.QRCodeScale--;
System.Drawing.Image imageNew = qrCodeEncoder.Encode(Content);
image = new System.Drawing.Bitmap(imageNew);
imageNew.Dispose();
imageNew = null;
}
}
#endregion
//當目標圖片尺寸大於二維碼尺寸時,將二維碼繪制在目標尺寸白色畫布的中心位置
if (image.Width < size)
{
//新建空白繪圖
System.Drawing.Bitmap panel = new System.Drawing.Bitmap(size, size);
System.Drawing.Graphics graphic0 = System.Drawing.Graphics.FromImage(panel);
int p_left = 0;
int p_top = 0;
if (image.Width <= size) //如果原圖比目標形狀寬
{
p_left = (size - image.Width) / 2;
}
if (image.Height <= size)
{
p_top = (size - image.Height) / 2;
}
//將生成的二維碼圖像粘貼至繪圖的中心位置
graphic0.DrawImage(image, p_left, p_top, image.Width, image.Height);
image = new System.Drawing.Bitmap(panel);
panel.Dispose();
panel = null;
graphic0.Dispose();
graphic0 = null;
}
}
#endregion
}
#endregion
return image;
}
//生成二維碼方法3 text為文本或網址等內容,imgurl則為圖片的網址
public static void GetTwoCodeMethoThree(string text, string imgurl = "")
{
try
{
String data = text;
if (!string.IsNullOrEmpty(data))
{
QRCodeEncoder qrCodeEncoder = new QRCodeEncoder();
qrCodeEncoder.QRCodeEncodeMode = QRCodeEncoder.ENCODE_MODE.BYTE;//編碼方式:BYTE 能支持中文,ALPHA_NUMERIC 掃描出來的都是數
qrCodeEncoder.QRCodeScale = 4;//大小:值越大生成的二維碼圖片像素越高
qrCodeEncoder.QRCodeVersion = 8;//版本
qrCodeEncoder.QRCodeErrorCorrect = QRCodeEncoder.ERROR_CORRECTION.M;//錯誤校驗、更正等級
Image image = CreateQRCode(text, QRCodeEncoder.ENCODE_MODE.BYTE, QRCodeEncoder.ERROR_CORRECTION.M, 8, 4, 0, 5);
//System.Drawing.Image image = qrCodeEncoder.Encode(data);
System.IO.MemoryStream MStream = new System.IO.MemoryStream();
image.Save(MStream, System.Drawing.Imaging.ImageFormat.Png);
System.IO.MemoryStream MStream1 = new System.IO.MemoryStream();
System.Drawing.Image codeimg;
Image ImageWeixin;
if (!string.IsNullOrEmpty(imgurl))
{
try
{
//獲得網絡上的圖片
System.Net.WebRequest webreq = System.Net.WebRequest.Create(imgurl);
System.Net.WebResponse webres = webreq.GetResponse();
Stream stream = webres.GetResponseStream();
ImageWeixin = Image.FromStream(stream);
stream.Close();
//貼圖
codeimg = CombinImage(image, ImageWeixin);
codeimg.Save(MStream1, System.Drawing.Imaging.ImageFormat.Png);
}
catch { }
}
//codeimg.Save(MStream1, System.Drawing.Imaging.ImageFormat.Png);
//string filename = text + DateTime.Now.ToString("yyyymmddhhmmssfff").ToString() + ".png";
//string filepath = HttpContext.Current.Server.MapPath(PortraitApp) + "\\" + filename;
//System.IO.FileStream fs = new System.IO.FileStream(filepath, System.IO.FileMode.OpenOrCreate, System.IO.FileAccess.Write);
//codeimg.Save(fs, System.Drawing.Imaging.ImageFormat.Png);
//string RetureFile = System.Configuration.ConfigurationManager.AppSettings["RetureFile"].ToString();
//直接輸出圖片 不保存
HttpContext.Current.Response.ClearContent();
HttpContext.Current.Response.ContentType = "image/png";
HttpContext.Current.Response.BinaryWrite(MStream1.ToArray());
image.Dispose();
MStream.Dispose();
MStream1.Dispose();
}
HttpContext.Current.Response.Flush();
HttpContext.Current.Response.End();
//return url;
}
catch (Exception ex)
{
HttpContext.Current.Response.ClearContent();
HttpContext.Current.Response.ContentType = "text/xml";
HttpContext.Current.Response.Write("操作異常:" + ex.ToString());
HttpContext.Current.Response.Flush();
HttpContext.Current.Response.End();
}
}
/// <summary>
/// 調用此函數后使此兩種圖片合並,類似相冊,有個
/// 背景圖,中間貼自己的目標圖片,注意參數不同 destImg使用的是已經初始化的Image,可用於網址類的圖片
/// </summary>
/// <param name="imgBack">粘貼的源圖片</param>
/// <param name="destImg">粘貼的目標圖片</param>
public static Image CombinImage(Image imgBack, Image destImg, int Lenth = 40)
{
Image img = destImg; //照片圖片
if (img.Height != Lenth || img.Width != Lenth)
{
img = KiResizeImage(img, Lenth, Lenth, 0);
//圓角處理 此處后來優化后調用一次就可以了
img = CreateRoundedCorner(img, "", "TopLeft");
img = CreateRoundedCorner(img, "", "TopRight");
img = CreateRoundedCorner(img, "", "BottomLeft");
img = CreateRoundedCorner(img, "", "BottomRight");
}
Graphics g = Graphics.FromImage(imgBack);
g.DrawImage(imgBack, 0, 0, imgBack.Width + 5, imgBack.Height + 5); //g.DrawImage(imgBack, 0, 0, 相框寬, 相框高);
g.FillRectangle(System.Drawing.Brushes.White, imgBack.Width / 2 - img.Width / 2 - 1, imgBack.Width / 2 - img.Width / 2 - 1, 1, 1);//相片四周刷一層黑色邊框
//g.DrawImage(img, 照片與相框的左邊距, 照片與相框的上邊距, 照片寬, 照片高);
g.DrawImage(img, imgBack.Width / 2 - img.Width / 2, imgBack.Width / 2 - img.Width / 2, img.Width, img.Height);
GC.Collect();//資源釋放
return imgBack;
}
/// <summary>
/// 調用此函數后使此兩種圖片合並,類似相冊,有個
/// 背景圖,中間貼自己的目標圖片 參數不同,destImg使用的是本地路徑
/// </summary>
/// <param name="imgBack">粘貼的源圖片</param>
/// <param name="destImg">粘貼的目標圖片</param>
public static Image CombinImage(Image imgBack, string destImg)
{
Image img = Image.FromFile(destImg); //照片圖片
if (img.Height != 65 || img.Width != 65)
{
img = KiResizeImage(img, 45, 45, 0);
}
Graphics g = Graphics.FromImage(imgBack);
g.DrawImage(imgBack, 0, 0, imgBack.Width, imgBack.Height); //g.DrawImage(imgBack, 0, 0, 相框寬, 相框高);
//g.FillRectangle(System.Drawing.Brushes.White, imgBack.Width / 2 - img.Width / 2 - 1, imgBack.Width / 2 - img.Width / 2 - 1,1,1);//相片四周刷一層黑色邊框
//g.DrawImage(img, 照片與相框的左邊距, 照片與相框的上邊距, 照片寬, 照片高);
g.DrawImage(img, imgBack.Width / 2 - img.Width / 2, imgBack.Width / 2 - img.Width / 2, img.Width, img.Height);
GC.Collect();
return imgBack;
}
//創建圖層圓角
public static Image CreateRoundedCorner(Image image, string sDstFilePath, string sCornerLocation)
{
Graphics g = Graphics.FromImage(image);
g.SmoothingMode = SmoothingMode.HighQuality;
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.CompositingQuality = CompositingQuality.HighQuality;
Rectangle rect = new Rectangle(0, 0, image.Width, image.Height);
GraphicsPath rectPath = CreateRoundRectanglePath(rect, image.Width / 10, sCornerLocation); //構建圓角外部路徑
Brush b = new SolidBrush(Color.White);//圓角背景白色
g.DrawPath(new Pen(b), rectPath);
g.FillPath(b, rectPath);
g.Dispose();
//image.Save(sDstFilePath, ImageFormat.Png);
return image;
//image.Dispose();
}
//處理圓角 上下左右
private static GraphicsPath CreateRoundRectanglePath(Rectangle rect, int radius, string sPosition)
{
GraphicsPath rectPath = new GraphicsPath();
switch (sPosition)
{
case "TopLeft":
{
rectPath.AddArc(rect.Left, rect.Top, radius * 2, radius * 2, 180, 90);
rectPath.AddLine(rect.Left, rect.Top, rect.Left, rect.Top + radius);
break;
}
case "TopRight":
{
rectPath.AddArc(rect.Right - radius * 2, rect.Top, radius * 2, radius * 2, 270, 90);
rectPath.AddLine(rect.Right, rect.Top, rect.Right - radius, rect.Top);
break;
}
case "BottomLeft":
{
rectPath.AddArc(rect.Left, rect.Bottom - radius * 2, radius * 2, radius * 2, 90, 90);
rectPath.AddLine(rect.Left, rect.Bottom - radius, rect.Left, rect.Bottom);
break;
}
case "BottomRight":
{
rectPath.AddArc(rect.Right - radius * 2, rect.Bottom - radius * 2, radius * 2, radius * 2, 0, 90);
rectPath.AddLine(rect.Right - radius, rect.Bottom, rect.Right, rect.Bottom);
break;
}
}
return rectPath;
}
/// <summary>
/// Resize圖片 裁剪
/// </summary>
/// <param name="bmp">原始Bitmap</param>
/// <param name="newW">新的寬度</param>
/// <param name="newH">新的高度</param>
/// <param name="Mode">保留着,暫時未用</param>
/// <returns>處理以后的圖片</returns>
public static Image KiResizeImage(Image bmp, int newW, int newH, int Mode)
{
try
{
Image b = new Bitmap(newW, newH);
Graphics g = Graphics.FromImage(b);
// 插值算法的質量
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.DrawImage(bmp, new Rectangle(0, 0, newW, newH), new Rectangle(0, 0, bmp.Width, bmp.Height), GraphicsUnit.Pixel);
g.Dispose();
return b;
}
catch
{
return null;
}
}
//二維碼解碼
/// <summary>
/// 二維碼解碼
/// </summary>
/// <param name="filePath">圖片路徑</param>
/// <returns></returns>
public string CodeDecoder(string filePath)
{
if (!System.IO.File.Exists(filePath))
return null;
Bitmap myBitmap = new Bitmap(Image.FromFile(filePath));
QRCodeDecoder decoder = new QRCodeDecoder();
string decodedString = decoder.decode(new QRCodeBitmapImage(myBitmap));
return decodedString;
}
圖片地址:http://imgsrc.baidu.com/image/c0%3Dshijue1%2C0%2C0%2C294%2C40/sign=729f32ebc9cec3fd9f33af36bee1be4a/fd039245d688d43f4c195ed5771ed21b0ef43b61.jpg
例子:http://192.168.2.228/api/Counselor/GetCodeImg?text=sb&imgurl=http://imgsrc.baidu.com/image/c0%3Dshijue1%2C0%2C0%2C294%2C40/sign=729f32ebc9cec3fd9f33af36bee1be4a/fd039245d688d43f4c195ed5771ed21b0ef43b61.jpg
調用api 生成圖片如下
掃碼即可得出text的內容