前段时间在网上看到新浪有一个提交文本(Html代码),自动上传图片的功能,觉得倒是很[实用,稍一琢磨,自己也写了这么一个东东。
根据所传入的Html代码,获取标签中的图片标签,将图片复制到当前服务器,替换Html代码中图片标签的src属性值。如果需要,还可以打上水印,堂堂正正的说版权归本公司(个人)所有,哈!
以下是主程序代码:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using System.Net;
using System.Drawing;
using System.Web;
using System.IO;
using System.Drawing.Imaging;

namespace JL.SWSystem.SWCommon.Mrhgw


{

/**//// <summary>
/// 根据传入的文本自动上传图片。
/// </summary>
public class ImageUploadAutomatic

{


静态构造器#region 静态构造器


/**//// <summary>
/// 静态构造器。
/// </summary>
static ImageUploadAutomatic()

{
htmimes[".jpe"] = "image/jpeg";
htmimes[".jpeg"] = "image/jpeg";
htmimes[".jpg"] = "image/jpeg";
htmimes[".png"] = "image/png";
htmimes[".gif"] = "image/gif";
htmimes[".tif"] = "image/tiff";
htmimes[".tiff"] = "image/tiff";
htmimes[".bmp"] = "image/bmp";
}

#endregion


变量#region 变量


/**//// <summary>
/// 存放包含编码解码器的多用途网际邮件扩充协议 (MIME) 类型的字符串的集合对象。
/// </summary>
private static Hashtable htmimes = new Hashtable();

/**//// <summary>
/// 传入的文本。
/// </summary>
private static string text = "";

/**//// <summary>
/// 文件上传的路径(非虚拟路径)。
/// </summary>
private static string filePath = "";

/**//// <summary>
/// 图片的引用路径(非虚拟路径)。
/// </summary>
private static string refersImagePath = "";

/**//// <summary>
/// 是否标记图片水印。
/// </summary>
private static bool isSignWatermark = false;

/**//// <summary>
/// 水印文本(以字符“|”标记换行。图片水印和文字水印选其一,优先图片水印)。
/// </summary>
private static string watermarkChars = "66xq.com";

/**//// <summary>
/// 水印图片(非虚拟路径。图片水印和文字水印选其一,优先图片水印)。
/// </summary>
private static string watermarkImage = "";

/**//// <summary>
/// 集合对象。
/// </summary>
private static List<ParamItem> imgPathColl = null;

/**//// <summary>
/// 水印图片。
/// </summary>
private static Image imgWatermark = null;

#endregion


属性#region 属性


/**//// <summary>
/// 获取或设置传入的文本。
/// </summary>
public static string Text

{

get
{ return text; }

set
{ text = value; }
}


/**//// <summary>
/// 获取或设置文件上传的路径(非虚拟路径)。
/// </summary>
public static string FilePath

{

get
{ return filePath; }

set
{ filePath = value; }
}


/**//// <summary>
/// 获取或设置图片的引用路径(非虚拟路径)。
/// </summary>
public static string RefersImagePath

{

get
{ return refersImagePath; }

set
{ refersImagePath = value; }
}


/**//// <summary>
/// 获取或设置是否标记图片水印。
/// </summary>
public static bool IsSignWatermark

{

get
{ return isSignWatermark; }

set
{ isSignWatermark = true; }
}


/**//// <summary>
/// 获取或设置水印文本(以字符“|”标记换行。图片水印和文字水印选其一,优先图片水印)。
/// </summary>
public static string WatermarkChars

{

get
{ return watermarkChars; }

set
{ watermarkChars = value; }
}


/**//// <summary>
/// 获取或设置水印图片(非虚拟路径。图片水印和文字水印选其一,优先图片水印)。
/// </summary>
public static string WatermarkImage

{

get
{ return watermarkImage; }

set
{ watermarkImage = value; }
}


/**//// <summary>
/// 获取已上传图片的集合对象。
/// </summary>
public static List<ParamItem> ImgPathColl

{

get
{ return imgPathColl; }
}


#endregion


重置所有参数#region 重置所有参数


/**//// <summary>
/// 重置所有参数。
/// </summary>
public static void Reset()

{
text = "";
filePath = "";
refersImagePath = "";
isSignWatermark = false;
watermarkChars = "";
watermarkImage = "";
imgPathColl = null;
}

#endregion


提交操作#region 提交操作


/**//// <summary>
/// 提交操作。
/// </summary>
public static void Submit()

{
if (text.Trim().Length == 0) return;
imgPathColl = new List<ParamItem>();

const string PATTERN_IMG = "<img\\s+[^>]*?src=[\"']?([^'\"\\s>]+)[\"']?[^>]*?>";
text = Regex.Replace(text, PATTERN_IMG, new MatchEvaluator(ImageUploadAutomatic.ReplaceCC), RegexOptions.IgnoreCase);

if (null != imgWatermark)

{
imgWatermark.Dispose();
imgWatermark = null;
}
}


/**//// <summary>
/// 搜索指定的匹配项,替换图片路径。
/// </summary>
/// <param name="match">捕获的正则匹配项</param>
/// <returns></returns>
public static string ReplaceCC(Match match)

{
if (!match.Success) return "";

HttpWebRequest req = null;
HttpWebResponse rep = null;
Image img = null;
string result = match.Value;

for(int i=0;i<match.Groups.Count;i++)

{
if (i == 0) continue;
Group gc = match.Groups[i];

try

{
if (gc.Value.Trim().Length == 0) return result;

string newFilename = CreateNewFilename(gc.Value);
if (newFilename == string.Empty) return result;

if (isSignWatermark && watermarkImage.Trim().Length > 0 && null == imgWatermark)

{
imgWatermark = Image.FromFile(HttpContext.Current.Server.MapPath(watermarkImage));
}

//首先查看该图片是不是本站内的图片。
if (File.Exists(HttpContext.Current.Server.MapPath(gc.Value)))

{
img = Image.FromFile(HttpContext.Current.Server.MapPath(gc.Value));
}
else

{
//其它网站的图片资源。
//获取图片资源。
req = (HttpWebRequest)HttpWebRequest.Create(gc.Value);
rep = (HttpWebResponse)req.GetResponse();

//生成图片。
img = Image.FromStream(rep.GetResponseStream());
}

//标记水印。
if (isSignWatermark)

{
if (watermarkImage.Trim().Length > 0)
img = ImageWatermark.MarkImage(img, imgWatermark);
else
img = ImageWatermark.MarkText(img);
}

//获取文件扩展名。
string sEx = newFilename.Substring(newFilename.LastIndexOf(".")).ToLower();
//保存图像。
SaveImage(img, System.Web.HttpContext.Current.Server.MapPath(filePath + "/" + newFilename), GetCodecInfo((string)htmimes[sEx]));
//添加上传路径到集合中,供其它地方调用。
imgPathColl.Add(new ParamItem(gc.Value, filePath + "/" + newFilename));
//替换图片路径。
result = result.Replace(gc.Value, refersImagePath + "/" + newFilename);
}
catch (System.UriFormatException)

{
//此处屏蔽由于错误的URI或相对地址的站内url所引发的异常,
//并复原返回值。
result = match.Value;
}
catch (Exception ex)

{
throw ex;
}
finally

{
if (null != img)

{
img.Dispose();
img = null;
}

if (null != rep)

{
rep.Close();
rep = null;
}
}

}

return result;
}


/**//// <summary>
/// 保存图片
/// </summary>
/// <param name="image">Image 对象</param>
/// <param name="savePath">保存路径</param>
/// <param name="ici">指定格式的编解码参数</param>
private static void SaveImage(System.Drawing.Image image, string savePath, ImageCodecInfo ici)

{
//设置 原图片 对象的 EncoderParameters 对象
EncoderParameters parameters = new EncoderParameters(1);
parameters.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, ((long)90));
image.Save(savePath, ici, parameters);
parameters.Dispose();
}


/**//// <summary>
/// 获取图像编码解码器的所有相关信息
/// </summary>
/// <param name="mimeType">包含编码解码器的多用途网际邮件扩充协议 (MIME) 类型的字符串</param>
/// <returns>返回图像编码解码器的所有相关信息</returns>
private static ImageCodecInfo GetCodecInfo(string mimeType)

{
ImageCodecInfo[] CodecInfo = ImageCodecInfo.GetImageEncoders();
foreach (ImageCodecInfo ici in CodecInfo)

{
if (ici.MimeType == mimeType) return ici;
}
return null;
}



#endregion


生成新的图片文件名称#region 生成新的图片文件名称


/**//// <summary>
/// 生成新的图片名称。
/// </summary>
/// <param name="preImagePath">原文件路径</param>
/// <returns>返回新的图片名称</returns>
private static string CreateNewFilename(string preImagePath)

{
//遍历先前加入集合中的图片,看是否存在相同路径的图片,
//如果存在,则返回以前加入集合的新图片名称。
foreach (ParamItem item in imgPathColl)

{
if (preImagePath.Trim().ToLower() == item.PreImagePath.Trim().ToLower())
return string.Empty;
}

preImagePath = preImagePath.Trim();
int index = preImagePath.LastIndexOf(".");
if (index < 0) return string.Empty;

return Guid.NewGuid().ToString() + preImagePath.Substring(index, preImagePath.Length - index);
}

#endregion
}
}

以下是参数类代码:
using System;
using System.Text;

namespace JL.Automatic


{

/**//// <summary>
/// 参数类。
/// </summary>
public class ParamItem

{

/**//// <summary>
/// 默认构造器。
/// </summary>
public ParamItem()

{

}


/**//// <summary>
/// 构造器(重载二)。
/// </summary>
/// <param name="preImagePath">原图片地址</param>
/// <param name="currentImagePath">当前图片链接地址</param>
internal ParamItem(string preImagePath, string currentImagePath)

{
this.preImagePath = preImagePath;
this.currentImagePath = currentImagePath;
}


/**//// <summary>
/// 原图片地址。
/// </summary>
private string preImagePath = "";

/**//// <summary>
/// 当前图片链接地址。
/// </summary>
private string currentImagePath = "";


/**//// <summary>
/// 获取或设置原图片地址。
/// </summary>
public string PreImagePath

{

get
{ return this.preImagePath; }

set
{ this.preImagePath = value; }
}


/**//// <summary>
/// 获取或设置当前图片链接地址。
/// </summary>
public string CurrentImagePath

{

get
{ return this.currentImagePath; }

set
{ this.currentImagePath = value; }
}
}
}

以下是生成水图的代码:
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;

namespace JL.SWSystem.SWCommon.Mrhgw


{

/**//// <summary>
/// 标记水印。
/// </summary>
public class ImageWatermark

{

标记文本水印#region 标记文本水印


/**//// <summary>
/// 标记文本水印。
/// </summary>
/// <param name="preImage">原图片</param>
/// <returns></returns>
public static Image MarkText(Image imgPhoto)

{
string copyrightString = "66xq.com";
int phWidth = imgPhoto.Width;
int phHeight = imgPhoto.Height;

//Bitmap bmPhoto = new Bitmap(phWidth, phHeight, PixelFormat.Format24bppRgb);
Bitmap bmPhoto = new Bitmap(imgPhoto);
Bitmap bmWatermark = new Bitmap(imgPhoto);
bmPhoto.SetResolution(72, 72);
Graphics grPhoto = Graphics.FromImage(imgPhoto);

grPhoto.SmoothingMode = SmoothingMode.AntiAlias;
grPhoto.CompositingQuality = CompositingQuality.HighQuality;
grPhoto.DrawImage(
imgPhoto,
new Rectangle(0, 0, phWidth, phHeight),
0,
0,
phWidth,
phHeight,
GraphicsUnit.Pixel);


int[] sizes = new int[]
{ 16, 14, 12, 10, 8, 6, 4 };
Font crFont = null;
SizeF crSize = new SizeF();

crFont = new Font("Lucida Sans U
", 45,
FontStyle.Bold);
crSize = grPhoto.MeasureString(copyrightString,
crFont);

// for (int i=0 ;i<7; i++)
// {
// crFont = new Font("arial", sizes[i],
// FontStyle.Bold);
// crSize = grPhoto.MeasureString(Copyright,
// crFont);
//
// if((ushort)crSize.Width < (ushort)phWidth)
// break;
// }

int yPixlesFromBottom = (int)(phHeight * .05);
//float yPosFromBottom = ((phHeight - yPixlesFromBottom)-(crSize.Height/2));
float yPosFromBottom = (phHeight - 100);
float xCenterOfImg = (phWidth - 180);

StringFormat StrFormat = new StringFormat();
StrFormat.Alignment = StringAlignment.Center;

SolidBrush semiTransBrush2 =
new SolidBrush(Color.FromArgb(100, 0, 0, 0));

grPhoto.DrawString(copyrightString,
crFont,
semiTransBrush2,
new PointF(xCenterOfImg + 1, yPosFromBottom + 1),
StrFormat);

SolidBrush semiTransBrush = new SolidBrush(
Color.FromArgb(100, 255, 255, 255));

grPhoto.DrawString(copyrightString,
crFont,
semiTransBrush,
new PointF(xCenterOfImg, yPosFromBottom),
StrFormat);

Graphics g = Graphics.FromImage(bmPhoto);
g.SmoothingMode = SmoothingMode.AntiAlias;
g.CompositingQuality = CompositingQuality.HighQuality;
g.DrawString(copyrightString, crFont, semiTransBrush, new PointF(250, 10), StrFormat);

return imgPhoto;

}

#endregion


标记图片水印#region 标记图片水印


/**//// <summary>
/// 标记图片水印。
/// </summary>
/// <param name="imgPhoto">原图片</param>
/// <param name="imgWatermark">背景图片</param>
/// <returns></returns>
public static Image MarkImage(Image imgPhoto, Image imgWatermark)

{
int phWidth = imgPhoto.Width;
int phHeight = imgPhoto.Height;

int wmWidth = imgWatermark.Width;
int wmHeight = imgWatermark.Height;


//Bitmap bmPhoto = new Bitmap(phWidth, phHeight, PixelFormat.Format24bppRgb);
Bitmap bmPhoto = new Bitmap(imgPhoto);
Bitmap bmWatermark = new Bitmap(bmPhoto);
Graphics grPhoto = Graphics.FromImage(bmPhoto);
grPhoto.SmoothingMode = SmoothingMode.AntiAlias;
grPhoto.CompositingQuality = CompositingQuality.HighQuality;


bmWatermark.SetResolution(
imgPhoto.HorizontalResolution,
imgPhoto.VerticalResolution);

Graphics grWatermark = Graphics.FromImage(bmWatermark);


ImageAttributes imageAttributes =
new ImageAttributes();
ColorMap colorMap = new ColorMap();

colorMap.OldColor = Color.FromArgb(255, 0, 255, 0);
colorMap.NewColor = Color.FromArgb(0, 0, 0, 0);

ColorMap[] remapTable =
{ colorMap };

imageAttributes.SetRemapTable(remapTable, ColorAdjustType.Bitmap);


float[][] colorMatrixElements =
{

new float[]
{1.0f, 0.0f, 0.0f, 0.0f, 0.0f},

new float[]
{0.0f, 1.0f, 0.0f, 0.0f, 0.0f},

new float[]
{0.0f, 0.0f, 1.0f, 0.0f, 0.0f},

new float[]
{0.0f, 0.0f, 0.0f, 0.3f, 0.0f},

new float[]
{0.0f, 0.0f, 0.0f, 0.0f, 1.0f}
};

ColorMatrix wmColorMatrix = new
ColorMatrix(colorMatrixElements);

//imageAttributes.SetColorMatrix(wmColorMatrix,
// ColorMatrixFlag.Default,
// ColorAdjustType.Bitmap);

int xPosOfWm = ((phWidth - wmWidth) - 10);
int yPosOfWm = (phHeight - wmHeight) - 10;

grWatermark.DrawImage(imgWatermark,
new Rectangle(xPosOfWm, yPosOfWm, wmWidth,
wmHeight),
0,
0,
wmWidth,
wmHeight,
GraphicsUnit.Pixel,
imageAttributes);

imgPhoto = bmWatermark;

grPhoto.Dispose();
grWatermark.Dispose();

return imgPhoto;
}

#endregion
}
}

以下是程序引用代码:
string content = ""; //Html标签。
ImageUploadAutomatic.Text = content; //设置Html标签。
ImageUploadAutomatic.FilePath = "../Images/Uploads"; //设置图片上传路径。
ImageUploadAutomatic.RefersImagePath= "/Images/Uploads"; //设置图片引用路径。
ImageUploadAutomatic.IsSignWatermark = true; //确定生成水印。
ImageUploadAutomatic.WatermarkImage = "../Images/Mark.png"; //水印图片路径。
ImageUploadAutomatic.Submit(); //提交生成。
content = ImageUploadAutomatic.Text; //此处返回修改后的Html标签(仅修改了图片的链接地址)。

【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· [AI/GPT/综述] AI Agent的设计模式综述