您的位置:首页 > 编程语言 > ASP

asp.net图片添加水印以及GDI+ 中发生一般性错误的解决方法

2012-02-28 21:33 639 查看
前台代码:

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Asp.net上传图片并添加水印</title>
</head>
<body>
<form id="form1" runat="server">
<div id="top">
Asp.Net上传并添加水印
</div>
<div id="content">
选择上传图片:<asp:FileUpload ID="upFileTest" runat="server" /><br />
<br />
<br />
<asp:RequiredFieldValidator ID="vUpFile" runat="server" ControlToValidate="upFileTest"
ErrorMessage="请选择要上传的文件!"></asp:RequiredFieldValidator><br />
<br />
<br />
<br />
<asp:Button ID="btnText" runat="server" OnClick="btnText_Click" Text="上传并添加文字水印" />
   
<br />
<br />
<br />
<br />
<asp:Label ID="lblStatus" runat="server"></asp:Label></div>
</form>
</body>
</html>


后台cs代码:

using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;

namespace 图片添加水印
{
public partial class WaterMarkTest : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
lblStatus.Visible = false;
}
}

private void Show(string str)
{
Response.Write("<script language='javascript'>alert('" + str + "')</script>");
}
private void upLoad()
{
string fullName = upFileTest.PostedFile.FileName;
string fileName = fullName.Substring(fullName.LastIndexOf("\\") + 1);
string marks = fullName.Substring(fullName.LastIndexOf(".") + 1); //图片格式
if (marks.ToLower() != "jpg" && marks.ToLower() != "gif")
{
Show("上传的文件格式不正确,请重新选择!");
}
else
{
string upFileName = Server.MapPath("upLoadFiles") + "\\" + System.DateTime.Now.ToString("yyyyMMddhhmmss") + "." + marks;
Session["filePath"] = upFileName;
Session["marks"] = marks;
upFileTest.PostedFile.SaveAs(upFileName);
}
}

protected void btnText_Click(object sender, EventArgs e)
{
upLoad();
//开始加文字水印
System.Drawing.Image img = System.Drawing.Image.FromFile(Session["filePath"].ToString());
Graphics g = Graphics.FromImage(img);
g.DrawImage(img, 0, 0, img.Width, img.Height);
Font f = new Font("黑体", 10); //字体的型号大小
Brush b = new SolidBrush(Color.FromArgb(70, Color.WhiteSmoke));//画笔的颜色
string str = "水印名称";
g.DrawString(str, f, b, img.Width/2, img.Height*9/10);//水印的位置
g.Dispose();
string newFilePath = Server.MapPath("upLoadFiles") + "\\" + System.DateTime.Now.ToString("yyyyMMddhhmmss") + "."
                   + Session["marks"].ToString();
img.Save(newFilePath);
img.Dispose();
if (File.Exists(Session["filePath"].ToString()))
{
File.Delete(Session["filePath"].ToString());
}
lblStatus.Visible = true;
lblStatus.Text = "水印绘制成功!";

}
}
}


在编辑的过程中。出现过 GDI+ 中发生一般性错误。网上查了资料后发现,原因可能是:Bitmap 对象创建后没有释放。

Bitmap 对象或一个 图像 对象从一个文件, 构造时该文件仍保留锁定对于对象的生存期。 因此, 无法更改图像并将其保存回它产生相同的文件。

替代方法
• 创建非索引映像。
• 创建索引映像。
这两种情况下, 原始 位图 上调用 Bitmap.Dispose() 方法删除该文件上锁或删除要求, 流或内存保持活动。

创建非索引图像
即使原始映像被索引格式中该方法要求新图像位于每像素 (超过 8 位 -) -, 非索引像素格式。 此变通方法使用 Graphics.DrawImage() 方法来将映像复制到新 位图 对象:
1. 构造从流、 从内存, 或从文件原始 位图 。
2. 创建新 位图 的相同大小, 带有是超过 8 位 - - 像素 (BPP) 每像素格式。
3. 使用 Graphics.FromImage() 方法以获取有关二 位图 Graphics 对象。
4. 用于 Graphics.DrawImage() 绘制首 位图 到二 位图 。
5. 用于 Graphics.Dispose() 处置是 图形 。
6. 用于 Bitmap.Dispose() 是首 位图 处置。

创建索引映像
此解决办法在索引格式创建一个 Bitmap 对象:
1. 构造从流、 从内存, 或从文件原始 位图 。
2. 创建新 位图 具有相同的大小和像素格式作为首 位图 。
3. 使用 Bitmap.LockBits() 方法来锁定整个图像对于两 Bitmap 对象以其本机像素格式。
4. 使用 Marshal.Copy 函数或其他内存复制函数来从首 位图 复制到二 位图 图像位。
5. 使用 Bitmap.UnlockBits() 方法可以解锁两 Bitmap 对象。
6. 用于 Bitmap.Dispose() 是首 位图 处置。
由于外国人的思维和我们不一样,我重新用实例解释一下,我这里使用的是创建非索引图像。

private void ToolStripMenuItem_Click(object sender, EventArgs e)
{
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
//创建一个bitmap类型的bmp变量来读取文件。

Bitmap bmp = new Bitmap(openFileDialog1 .FileName );
//新建第二个bitmap类型的bmp2变量,我这里是根据我的程序需要设置的。

Bitmap bmp2 = new Bitmap(1024, 768, PixelFormat.Format16bppRgb555);
//将第一个bmp拷贝到bmp2中

Graphics draw = Graphics.FromImage(bmp2);
draw.DrawImage(bmp,0,0);
pictureBox1.Image = (Image)bmp2 ;//读取bmp2到picturebox

FILE = openFileDialog1.FileName;
openFileDialog1.Dispose();
draw.Dispose();
bmp.Dispose();//释放bmp文件资源

}
}

通过以上的读取文件,在保存的时候就不会出现错误了。

但是也不是这个问题,最后发现,问题其实出在。图片在加水印前和加水印后保存的文件夹是同一个,导致错误。
解决的方法是新建一个保存加水印后的图片的文件夹。及:
将代码:

string newFilePath = Server.MapPath("upLoadFiles") + "\\" + System.DateTime.Now.ToString("yyyyMMddhhmmss") + "." + Session["marks"].ToString();

改为:string newFilePath = Server.MapPath("newMarkFiles") + "\\" + System.DateTime.Now.ToString("yyyyMMddhhmmss") + "."+ Session["marks"].ToString();

新建文件夹的名称是:newMarkFiles
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: