概述
博主前面讲述到可以通过python下的flask框架部署自己的模型,也讲述过通过aistudio部署自己的paddle模型(可以参考基于aistudio部署自己的paddle模型),然后通过web请求实现调用。这里的webapi调用软件主要针对aistudio部署平台的webapi进行请求调用,如果是自己部署的服务,也可以参考该教程(仅需求修改解析结果json的部分即可)。先说一下软件设计的特性:
1、支持对webapi的url进行加密解密,避免站点和参数信息直接暴露给用户
2、支持webapi的结果为图片或者字符串。(其中图片以base64的形式表示)
3、在选择文件时支持点选和拖拽
软件主要由界面代码、主程序、字符串加密类、webapi调用类、图像处理类实现,本博文后面有软件下载地址。
1、界面设计
软件界面设计如下所示,其中有一个加密按钮,用于加密输出框的url地址。当软件要交付给其他人测试时,可以将加密按钮删除。
2、主程序的基本实现
这里主要实现各种按钮的点击事件(如点击测试按钮[button1]发送http请求调用webapi、点击加密按钮[button1]则加密输入框中的字符串、点击下方的图片控件[pictureBox1]则选择图片文件),同时也实现了pictureBox1的文件拖入效果、结果展示函数set_result(支持图像展示、字符串展示)。
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
pictureBox1.AllowDrop = true;//设置控件允许拖拽文件
}
public string base64_img = null;
private void set_result(string result) {
if (ImgUtils.IsBase64(result))
{
Image img = ImgUtils.ConvertBase64ToImage(result);
pictureBox2.Image = img;
richTextBox1.Visible = false;
pictureBox2.Visible = true;
}
else
{
richTextBox1.Text = result;
richTextBox1.Visible = true;
pictureBox2.Visible = false;
}
}
private void button1_Click(object sender, EventArgs e)
{
string url = DES.Decrypt(apiKey_input.Text);
string content= "{"input": "" + base64_img + "" }";
string result = NetUtils.Post(url, content);
set_result(result);
}
private void pictureBox1_Click(object sender, EventArgs e)
{
OpenFileDialog ofg = new OpenFileDialog();
ofg.Filter = "Image Files (*.jpg;*.bmp;*.png)|*.jpg;*.bmp;*.png";
ofg.Multiselect = false;
//调用对象的函数
if (ofg.ShowDialog() == DialogResult.OK)
{
//获取文件的路径
string filepath = ofg.FileName;
read_image(filepath);
}
}
private void read_image(string filepath) {
using (FileStream file = new FileStream(filepath, FileMode.Open))
{
Image img = Image.FromStream(file);
img = ImgUtils.resizeImg(img, pictureBox1.Width, pictureBox1.Height);
pictureBox1.Image = img;
base64_img = ImgUtils.ConvertImageToBase64(pictureBox1.Image);
set_result(base64_img);
}
}
private void button2_Click(object sender, EventArgs e)
{
string encrypt=DES.Encrypt(apiKey_input.Text);
string decrypt=DES.Decrypt(encrypt);
richTextBox1.Text = encrypt+"n"+ decrypt;
apiKey_input.Text = encrypt;
}
private void pictureBox1_DragDrop(object sender, DragEventArgs e)
{
string[] s = (string[])e.Data.GetData(DataFormats.FileDrop, false);
read_image(s[s.Length-1]);
}
private void pictureBox1_DragEnter(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(DataFormats.FileDrop))
{
e.Effect = DragDropEffects.All;
}
else
{
e.Effect = DragDropEffects.None;
}
}
}
2、字符串加密类
是一个静态工具类,用于实现字符串的加密解密,在本软件中主要用于webapi的url加密解密。
public class DES
{
static string encryptKey = "abcd";//定义密钥,长度为32位,故只能是4个字符
#region 加密字符串
/// <summary>
/// 加密字符串
/// </summary>
/// <param name="str">要加密的字符串</param>
/// <returns>加密后的字符串</returns>
public static string Encrypt(string str)
{
DESCryptoServiceProvider descsp = new DESCryptoServiceProvider();//实例化加/解密类对象
byte[] key = Encoding.Unicode.GetBytes(encryptKey);//定义字节数组,用来存储密钥
byte[] data = Encoding.Unicode.GetBytes(str);//定义字节数组,用来存储要加密的字符串
MemoryStream MStream = new MemoryStream();//实例化内存流对象
//使用内存流实例化加密流对象
CryptoStream CStream = new CryptoStream(MStream, descsp.CreateEncryptor(key, key), CryptoStreamMode.Write);
CStream.Write(data, 0, data.Length);//向加密流中写入数据
CStream.FlushFinalBlock();//释放加密流
return Convert.ToBase64String(MStream.ToArray());//返回加密后的字符串
}
#endregion
#region 解密字符串
/// <summary>
/// 解密字符串
/// </summary>
/// <param name="str">要解密的字符串</param>
/// <returns>解密后的字符串</returns>
public static string Decrypt(string str)
{
DESCryptoServiceProvider descsp = new DESCryptoServiceProvider();//实例化加/解密对象
byte[] key = Encoding.Unicode.GetBytes(encryptKey);//定义字节数组,用来存储密钥
byte[] data = Convert.FromBase64String(str);//定义字节数组,用来存储要解密的字符串
MemoryStream MStream = new MemoryStream();//实例化内存流对象
//使用内存流实例化解密流对象
CryptoStream CStream = new CryptoStream(MStream, descsp.CreateDecryptor(key, key), CryptoStreamMode.Write);
CStream.Write(data, 0, data.Length);//向解密流中写入数据
CStream.FlushFinalBlock();//释放解密流
return Encoding.Unicode.GetString(MStream.ToArray());//返回解密后的字符串
}
#endregion
}
3、webapi调用类
这里主要实现发生http请求调用webapi,并解析结果。如果是自己部署的服务,则需求修改本代码中结果解析的部分。
class NetUtils
{
#region Post请求
/// <summary>
/// http Post请求
/// </summary>
/// <param name="parameterData">参数</param>
/// <param name="serviceUrl">访问地址</param>
/// <param name="ContentType">默认 application/json , application/x-www-form-urlencoded,multipart/form-data,raw,binary </param>
/// <param name="Accept">默认application/json</param>
/// <returns></returns>
public static string Post(string serviceUrl, string parameterData, string ContentType = "application/json", string Accept = "application/json")
{
try
{
//先根据用户请求的uri构造请求地址
//string serviceUrl = string.Format("{0}/{1}", this.BaseUri, uri);
//创建Web访问对象
HttpWebRequest myRequest = (HttpWebRequest)WebRequest.Create(serviceUrl);
//把用户传过来的数据转成“UTF-8”的字节流
byte[] buf = System.Text.Encoding.GetEncoding("UTF-8").GetBytes(parameterData);
myRequest.Method = "POST";
//myRequest.Accept = "application/json";
//myRequest.ContentType = "application/json"; // //Content-Type: application/x-www-form-urlencoded
myRequest.AutomaticDecompression = DecompressionMethods.GZip;
myRequest.Accept = Accept;
//myRequest.ContentType = ContentType;
myRequest.ContentType = "application/json; charset=UTF-8";
myRequest.ContentLength = buf.Length;
myRequest.MaximumAutomaticRedirections = 1;
myRequest.AllowAutoRedirect = true;
//myRequest.Headers.Add("content-type", "application/json");
//myRequest.Headers.Add("accept-encoding", "gzip");
//myRequest.Headers.Add("accept-charset", "utf-8");
//发送请求
Stream stream = myRequest.GetRequestStream();
stream.Write(buf, 0, buf.Length);
stream.Close();
//通过Web访问对象获取响应内容
HttpWebResponse myResponse = (HttpWebResponse)myRequest.GetResponse();
//通过响应内容流创建StreamReader对象,因为StreamReader更高级更快
StreamReader reader = new StreamReader(myResponse.GetResponseStream(), Encoding.UTF8);
//string returnXml = HttpUtility.UrlDecode(reader.ReadToEnd());//如果有编码问题就用这个方法
string returnData = reader.ReadToEnd();//利用StreamReader就可以从响应内容从头读到尾
reader.Close();
myResponse.Close();
JObject jo = (JObject)JsonConvert.DeserializeObject(returnData);
try
{
return jo["result"]["output"].ToString();
}
catch (Exception ex)
{
return returnData;
}
}
catch (Exception ex)
{
return "接口调用失败";
}
}
#endregion
}
4、图像处理类
图像处理类主要实现base64字符串转image,image转base64字符串和iamge的resize。
class ImgUtils
{
private static char[] base64CodeArray = new char[]
{
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/', '='
};
public static bool IsBase64(string base64Str)
{
//string strRegex = "^([A-Za-z0-9+/]{4})*([A-Za-z0-9+/]{4}|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)$";
if (string.IsNullOrEmpty(base64Str))
return false;
else
{
if (base64Str.Contains(","))
base64Str = base64Str.Split(',')[1];
if (base64Str.Length % 4 != 0)
return false;
if (base64Str.Any(c => !base64CodeArray.Contains(c)))
return false;
}
try
{
return true;
}
catch (FormatException)
{
return false;
}
}
public static string ConvertImageToBase64(Image bmp)
{
try
{
MemoryStream ms = new MemoryStream();
bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
byte[] arr = new byte[ms.Length]; ms.Position = 0;
ms.Read(arr, 0, (int)ms.Length); ms.Close();
return Convert.ToBase64String(arr);
}
catch (Exception ex)
{
return "转换错误";
}
}
public static Image ConvertBase64ToImage(string base64String)
{
try
{
byte[] imageBytes = Convert.FromBase64String(base64String);
using (MemoryStream ms = new MemoryStream(imageBytes, 0, imageBytes.Length))
{
ms.Write(imageBytes, 0, imageBytes.Length);
return Image.FromStream(ms, true);
}
}
catch (Exception ex)
{
return null;
}
}
public static Image resizeImg(Image sourceImage, int targetWidth, int targetHeight)
{
int width;//图片最终的宽
int height;//图片最终的高
try
{
//获取图片宽度
int sourceWidth = sourceImage.Width;
//获取图片高度
int sourceHeight = sourceImage.Height;
System.Drawing.Imaging.ImageFormat format = sourceImage.RawFormat;
Bitmap targetPicture = new Bitmap(targetWidth, targetHeight);
Graphics g = Graphics.FromImage(targetPicture);
g.Clear(Color.White);
g.DrawImage(sourceImage, 0,0, targetWidth, targetHeight);
sourceImage.Dispose();
return targetPicture;
}
catch (Exception ex)
{
}
return null;
}
}
5、软件测试
软件的下载地址为:https://download.csdn.net/download/a486259/86505608
解压后即可运行,可以自己将上述代码复制到自己的vs项目中。
选择图片
点击测试
启动服务后再次测试
最后
以上就是善良白云为你收集整理的基于C#实现自己的webapi调用软件的全部内容,希望文章能够帮你解决基于C#实现自己的webapi调用软件所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复