Files

559 lines
22 KiB
C#
Raw Permalink Normal View History

2025-11-20 09:50:21 +08:00
using Models;
using Services.Manager;
using Services.Tool;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using System.Threading.Tasks;
using System.Web;
using System.Web.Hosting;
using System.Web.Mvc;
namespace UI.Controllers
{
public class ImgServerController : Controller
{
public JsonResult UpdateIcon()
{
try
{
string TimePath = HostingEnvironment.MapPath("~/Upload/APPicon/");//保存路径
var oFile = Request.Files[0];//获得上传的文件
if (oFile.ContentType.IndexOf("image/") < 0)
{
return Json(new
{
code = 1,//0表示成功
msg = "文件格式不对~",//
});
}
string ext = oFile.ContentType.Replace("image/", ".");
string fullPath = DateTime.Now.ToString("yyyy-MM-dd HH-mm-ss fff") + ext;
if (!Directory.Exists(TimePath))//判断文件夹是否存在
{
Directory.CreateDirectory(TimePath);//不存在则创建文件夹
}
oFile.SaveAs(TimePath + fullPath);
string ftpURLTwo = "uts-svr2.qicp.net:50/uts_Manager/am_FTP/APPicon/";
string filename = FtpUpload(TimePath + fullPath, ftpURLTwo);
return Json(filename);
}
catch (Exception ex)
{
LogHelp.WriteExceptionLog(ex);
return Json("");
}
}
public JsonResult Update()
{
try
{
string TimePath = HostingEnvironment.MapPath("~/Upload/Image/");//保存路径
TimePath += DateTime.Now.ToString("yyyy-MM-dd");
TimePath += "\\";
var oFile = Request.Files[0];//获得上传的文件
//获取后缀名
if (oFile.ContentType.IndexOf("image/") < 0)
{
return Json(new
{
code = 1,//0表示成功
msg = "文件格式不对~",//
});
}
string ext = oFile.ContentType.Replace("image/", ".");
//string fullPath = Guid.NewGuid().ToString() + ext;
string fullPath = DateTime.Now.ToString("yyyy-MM-dd HH-mm-ss fff") + ext;
if (!Directory.Exists(TimePath))//判断文件夹是否存在
{
Directory.CreateDirectory(TimePath);//不存在则创建文件夹
}
oFile.SaveAs(TimePath + fullPath);
//int c = oFile.ContentLength;//字节长度
FileInfo file = new FileInfo(TimePath + fullPath);
string imgUrl = TimePath + fullPath;
string UPUrl = HostingEnvironment.MapPath("~/Upload/Imgs/");//压缩后保存路径
string littleUrl = HostingEnvironment.MapPath("~/Upload/Img/");//压缩后保存路径
if (!Directory.Exists(UPUrl))//判断文件夹是否存在
{
Directory.CreateDirectory(UPUrl);//不存在则创建文件夹
}
string ur;//传递URL给前端
long size;
//缩略图
string urltwo = MakeThumbnail(imgUrl, littleUrl, 85, 85, "Cut");
if (CompressImage(imgUrl, UPUrl + file.Name))
{
using (FileStream fs = new FileStream(UPUrl + file.Name, FileMode.OpenOrCreate, FileAccess.Read))
{
size = fs.Length;
//异步压缩图
string ftpURL = "uts-svr2.qicp.net:50/uts_Manager/am_FTP/Image";
ur = FtpUpload(UPUrl + file.Name, ftpURL);
}
}
else
{
throw new Exception();
}
string ftpURLTwo = "uts-svr2.qicp.net:50/uts_Manager/am_FTP/Img";
ur = FtpUpload(urltwo, ftpURLTwo);
//删除本地文件
string issave = ConfigHelper.GetConfigString("IsSaveImg") ?? "0";
if (issave != "0")
{
System.IO.File.Delete(urltwo);
System.IO.File.Delete(UPUrl + fullPath);
}
var data1 = new
{
src = ur,
sizes = size
};
var Person = new
{
code = 0,//0表示成功
msg = "",//
data = data1
};
return Json(Person);//
}
catch (Exception e)
{
LogHelp.WriteExceptionLog(e, this.GetType().Name);
return null;
}
}
/// <summary>
/// 图片上传到ftp
/// </summary>
/// <param name="filename">源文件路径</param>
public string FtpUpload(string filename, string ftpServerIP)
{
string ftpUserID = "uts_manager";//ftp账号
string ftpPassword = "uts_Inhaos@all";//ftp密码
FileInfo fileInf = new FileInfo(filename);
FtpWebRequest reqFTP;
ServicePointManager.ServerCertificateValidationCallback =
new RemoteCertificateValidationCallback(ValidateServerCertificate);
try
{
// 根据uri创建FtpWebRequest对象
reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri("ftp://" + ftpServerIP + "/" + fileInf.Name));
// ftp用户名和密码
reqFTP.Credentials = new NetworkCredential(ftpUserID, ftpPassword);
// 默认为true连接不会被关闭
// 在一个命令之后被执行
reqFTP.KeepAlive = true;
//如果要连接的 FTP 服务器要求凭据并支持安全套接字层 (SSL),则应将 EnableSsl 设置为 true。如果不写会报出421错误服务不可用
reqFTP.EnableSsl = true;
// 指定执行什么命令
reqFTP.Method = WebRequestMethods.Ftp.UploadFile;
// 指定数据传输类型
reqFTP.UseBinary = true;
// 上传文件时通知服务器文件的大小
reqFTP.ContentLength = fileInf.Length;
// 缓冲大小设置为 10kb
int buffLength = 10480;
byte[] buff = new byte[buffLength];
int contentLen;
// 打开一个文件流 (System.IO.FileStream) 去读上传的文件
FileStream fs = fileInf.OpenRead();
try
{
// 把上传的文件写入流
Stream strm = reqFTP.GetRequestStream();
// 每次读文件流的buffLength kb
contentLen = fs.Read(buff, 0, buffLength);
// 流内容没有结束
while (contentLen != 0)
{
// 把内容从file stream 写入 upload stream
strm.Write(buff, 0, contentLen);
contentLen = fs.Read(buff, 0, buffLength);
}
// 关闭两个流
strm.Close();
fs.Close();
return fileInf.Name ;
}
catch (Exception ex)
{
Response.Write("Upload Error" + ex.Message);
}
}
catch (Exception e)
{
Response.Write("Upload Error" + e.Message);
}
return null;
}
/// <summary>
/// 从ftp获取图片
/// </summary>
/// <param name="url">路径</param>
/// <returns></returns>
public ActionResult FileImage(string url, string ftp = "")
{
//Logs.WriteLog("222获取图片开始"+DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff"));
if (ftp != "")
{
if (ftp == "app")
url = "ftp://uts-svr2.qicp.net:50/uts_Manager/am_FTP/APPicon/" + url;
else
url = "ftp://uts-svr2.qicp.net:50/uts_Manager/am_FTP/Image/" + url;
}
else
url = "ftp://uts-svr2.qicp.net:50/uts_Manager/am_FTP/Img/" + url;
FtpWebRequest ftpWeb;
try
{
ServicePointManager.ServerCertificateValidationCallback =
new RemoteCertificateValidationCallback(ValidateServerCertificate);
try
{
ftpWeb = (FtpWebRequest)FtpWebRequest.Create(url);//创建ftp连接
ftpWeb.Credentials = new NetworkCredential("uts_manager", "uts_Inhaos@all");//账号,密码
ftpWeb.KeepAlive = false;
ftpWeb.Timeout = 2000;
ftpWeb.ReadWriteTimeout = 2000;
ftpWeb.EnableSsl = true;
ftpWeb.Method = WebRequestMethods.Ftp.DownloadFile;
ftpWeb.UseBinary = true;
ftpWeb.UsePassive = true;
//AUTS.Services.Manager.Logs.WriteLog("获取图片数据开始" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff"));
WebResponse ftpResponse = (FtpWebResponse)ftpWeb.GetResponse();
//AUTS.Services.Manager.Logs.WriteLog("获取图片数据结束" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff"));
Stream ftpStream = ftpResponse.GetResponseStream();//获取图片流
MemoryStream outstream = new MemoryStream();//转成MS流
int bufferLen = 4096;//缓冲区
byte[] buffer = new byte[bufferLen];
int count = 0;
while ((count = ftpStream.Read(buffer, 0, bufferLen)) > 0)
{
outstream.Write(buffer, 0, count);
}
//var img = outstream.ToArray();
//Logs.WriteLog(img.ToString());
var img = outstream.ToArray();
ftpResponse.Close();
ftpStream.Close();
outstream.Close();
return File(img, "image/jpeg");//转成图片格式
//return new Task<byte[]>(() => outstream.ToArray());
}
catch (Exception e)
{
LogHelp.WriteExceptionLog(e, this.GetType().Name);
return null;
}
}
catch (Exception ex)
{
LogHelp.WriteExceptionLog(ex, this.GetType().Name);
return null;
}
}
/// <summary>
/// 无证书时跳过不报错
/// </summary>
/// <param name="sender"></param>
/// <param name="certificate"></param>
/// <param name="chain"></param>
/// <param name="sslPolicyErrors"></param>
/// <returns></returns>
public static bool ValidateServerCertificate
(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
return true;
}
/// <summary>
/// 压缩图片至n Kb以下
/// </summary>
/// <param name="img">图片</param>
/// <param name="format">图片格式</param>
/// <param name="targetLen">压缩后大小</param>
/// <param name="srcLen">原始大小</param>
/// <returns>压缩后的图片内存流</returns>
public static MemoryStream Zip(Image img, ImageFormat format, long targetLen, long srcLen = 0)
{
//设置允许大小偏差幅度 默认10kb
const long nearlyLen = 10240;
//返回内存流 如果参数中原图大小没有传递 则使用内存流读取
var ms = new MemoryStream();
if (0 == srcLen)
{
img.Save(ms, format);
srcLen = ms.Length;
}
//单位 由Kb转为byte 若目标大小高于原图大小,则满足条件退出
targetLen *= 1024;
if (targetLen >= srcLen)
{
ms.SetLength(0);
ms.Position = 0;
img.Save(ms, format);
return ms;
}
//获取目标大小最低值
var exitLen = targetLen - nearlyLen;
//初始化质量压缩参数 图像 内存流等
var quality = (long)Math.Floor(100.00 * targetLen / srcLen);
var parms = new EncoderParameters(1);
//获取编码器信息
ImageCodecInfo formatInfo = null;
var encoders = ImageCodecInfo.GetImageEncoders();
foreach (ImageCodecInfo icf in encoders)
{
if (icf.FormatID == format.Guid)
{
formatInfo = icf;
break;
}
}
//使用二分法进行查找 最接近的质量参数
long startQuality = quality;
long endQuality = 100;
quality = (startQuality + endQuality) / 2;
while (true)
{
//设置质量
parms.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, quality);
//清空内存流 然后保存图片
ms.SetLength(0);
ms.Position = 0;
}
}
#region
/// <summary>
/// 生成缩略图
/// </summary>
/// <param name="originalImagePath">源图路径(物理路径)</param>
/// <param name="thumbnailPath">缩略图路径(物理路径)</param>
/// <param name="width">缩略图宽度</param>
/// <param name="height">缩略图高度</param>
/// <param name="mode">生成缩略图的方式</param>
public string MakeThumbnail(string originalImagePath, string thumbnailPath, int width, int height, string mode)
{
ReturnResult result = new ReturnResult();
FileInfo info = new FileInfo(originalImagePath);
Image originalImage = Image.FromFile(originalImagePath);
int towidth = width;
int toheight = height;
int x = 0;
int y = 0;
int ow = originalImage.Width;
int oh = originalImage.Height;
switch (mode)
{
case "HW"://指定高宽缩放(可能变形)
break;
case "W"://指定宽,高按比例
toheight = originalImage.Height * width / originalImage.Width;
break;
case "H"://指定高,宽按比例
towidth = originalImage.Width * height / originalImage.Height;
break;
case "Cut"://指定高宽裁减(不变形)
if ((double)originalImage.Width / (double)originalImage.Height > (double)towidth / (double)toheight)
{
oh = originalImage.Height;
ow = originalImage.Height * towidth / toheight;
y = 0;
x = (originalImage.Width - ow) / 2;
}
else
{
ow = originalImage.Width;
oh = originalImage.Width * height / towidth;
x = 0;
y = (originalImage.Height - oh) / 2;
}
break;
default:
break;
}
//新建一个bmp图片
Image bitmap = new System.Drawing.Bitmap(towidth, toheight);
//新建一个画板
Graphics g = System.Drawing.Graphics.FromImage(bitmap);
//设置高质量插值法
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;
//设置高质量,低速度呈现平滑程度
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
//清空画布并以透明背景色填充
g.Clear(Color.Transparent);
//在指定位置并且按指定大小绘制原图片的指定部分
g.DrawImage(originalImage, new Rectangle(0, 0, towidth, toheight),
new Rectangle(x, y, ow, oh),
GraphicsUnit.Pixel);
try
{
if (!Directory.Exists(thumbnailPath))
{
Directory.CreateDirectory(thumbnailPath);
}
//以jpg格式保存缩略图
bitmap.Save(thumbnailPath + info.Name);
return thumbnailPath + info.Name;
//return thumbnailPath + info.Name;
}
catch (System.Exception e)
{
LogHelp.WriteExceptionLog(e, this.GetType().Name);
return null;
}
finally
{
originalImage.Dispose();
bitmap.Dispose();
g.Dispose();
}
}
#endregion
/// <summary>
/// 无损压缩图片
/// </summary>
/// <param name="originalFileFullName">原图片地址</param>
/// <param name="afterConversionFileFullName">压缩后保存图片地址</param>
/// <param name="flag">压缩质量数字越小压缩率越高1-100</param>
/// <param name="size">压缩后图片的最大大小</param>
/// <param name="isFirst">是否是第一次调用</param>
/// <returns></returns>
public static bool CompressImage(string originalFileFullName, string afterConversionFileFullName, int flag = 90, int size = 100, bool isFirst = true)
{
Image iSource = Image.FromFile(originalFileFullName);
ImageFormat tFormat = iSource.RawFormat;
//如果是第一次调用原始图像的大小小于要压缩的大小则直接复制文件并且返回true
FileInfo firstFileInfo = new FileInfo(originalFileFullName);
if (isFirst == true && firstFileInfo.Length < size * 1024)
{
firstFileInfo.CopyTo(afterConversionFileFullName);
return true;
}
int dHeight = iSource.Height / 2;
int dWidth = iSource.Width / 2;
int sW = 0, sH = 0;
//按比例缩放
Size tem_size = new Size(iSource.Width, iSource.Height);
if (tem_size.Width > dHeight || tem_size.Width > dWidth)
{
if ((tem_size.Width * dHeight) > (tem_size.Width * dWidth))
{
sW = dWidth;
sH = (dWidth * tem_size.Height) / tem_size.Width;
}
else
{
sH = dHeight;
sW = (tem_size.Width * dHeight) / tem_size.Height;
}
}
else
{
sW = tem_size.Width;
sH = tem_size.Height;
}
Bitmap ob = new Bitmap(dWidth, dHeight);
Graphics g = Graphics.FromImage(ob);
g.Clear(Color.WhiteSmoke);
g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
g.DrawImage(iSource, new Rectangle((dWidth - sW) / 2, (dHeight - sH) / 2, sW, sH), 0, 0, iSource.Width, iSource.Height, GraphicsUnit.Pixel);
g.Dispose();
//以下代码为保存图片时,设置压缩质量
EncoderParameters ep = new EncoderParameters();
long[] qy = new long[1];
qy[0] = flag;//设置压缩的比例1-100
EncoderParameter eParam = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, qy);
ep.Param[0] = eParam;
try
{
ImageCodecInfo[] arrayICI = ImageCodecInfo.GetImageEncoders();
ImageCodecInfo jpegICIinfo = null;
for (int x = 0; x < arrayICI.Length; x++)
{
if (arrayICI[x].FormatDescription.Equals("JPEG"))
{
jpegICIinfo = arrayICI[x];
break;
}
}
if (jpegICIinfo != null)
{
ob.Save(afterConversionFileFullName, jpegICIinfo, ep);
FileInfo fi = new FileInfo(afterConversionFileFullName);
if (fi.Length > 1024 * size)
{
var str = afterConversionFileFullName.Split('.').ToList();
var path = str.LastOrDefault();
path = HostingEnvironment.MapPath($"~/Upload/Image/{new Random().Next()}{DateTime.Now.ToString("yyyy_MM_dd_HH_mm_ss")}.{path}");
ob.Save(path, jpegICIinfo, ep);
//flag = flag - 10;
return CompressImage(path, afterConversionFileFullName, flag, size, false);
}
else
{
ob.Save(afterConversionFileFullName, jpegICIinfo, ep);
}
}
else
{
ob.Save(afterConversionFileFullName, tFormat);
}
return true;
}
catch(Exception ex)
{
LogHelp.WriteExceptionLog(ex);
return false;
}
finally
{
iSource.Dispose();
ob.Dispose();
//不是第一次就删除源文件
if (!isFirst)
{
System.IO.File.Delete(originalFileFullName);
}
}
}
}
}