原本系統網頁報表上沒有浮水印,現在要加入浮水印,以下一步一步介紹實作的過程。
前言
原本系統網頁報表上沒有浮水印,現在要加入浮水印,以下一步一步介紹實作的過程。
實作
直覺的想法就是設定網頁的底圖,如下,
<body style="background-image: url(mywatermark.gif); background-repeat: no-repeat; background-position: center;">
Q.那如果圖要動態產生出來呢(我們的需求是要顯示使用者及目前的時間)?
那就透過程式來動態產生圖,如下,
<body style="background-image: url(./Pub/GetWatermark.ashx); background-repeat: no-repeat; background-position: center;">
透過GetWatermark.ashx來動態產生有點透明的圖檔出來,程式如下,
/// <summary> /// 動態產生有點透明的圖片 /// </summary> /// <remarks> /// 因為要存取Session的資料,所以實作 IRequiresSessionState Interface /// </remarks> public class GetWatermark : IHttpHandler, IRequiresSessionState { /// <summary> /// 產生Watermark的圖片 /// </summary> /// <param name="context"></param> /// <remarks> /// </remarks> public void ProcessRequest(HttpContext context) { const string DefaultFontName = @"細明體"; int useWay = 0; //如果傳進來的是2,就使用黑色,不然就用淡色 int.TryParse(context.Request["way"] as string, out useWay); //設定輸出為gif檔 context.Response.ContentType = "image/gif"; int fontSize = 30; int bmpWidth = 500; int bmpHeight = 400; string watermark = @"使用者:{0},日期:{1},時間:{2}"; //建立Bitmap Bitmap bmp = new Bitmap(bmpWidth, bmpHeight); //設定使用者及時間,並將逗號改成換行符號 string watermarks = string.Format(watermark, context.Session["User_Name"] as string, DateTime.Now.ToString("yyyy/MM/dd", CultureInfo.InvariantCulture), DateTime.Now.ToString("HH:mm:ss")).Replace(",", Environment.NewLine); //建立Graphics Graphics canvas = Graphics.FromImage(bmp); //設定透明的Brush SolidBrush watermarkBrush; if (useWay == 2) { //如果是用蓋到畫面上的方式,Color就直接用黑色 watermarkBrush = new SolidBrush(Color.Black); } else { //如果是用底圖的話,Color就用淡一點 watermarkBrush = new SolidBrush(Color.FromArgb(128, 221, 221, 255)); } //設定底圖為白色 SolidBrush whiteBrush = new SolidBrush(Color.White); //將底圖畫成白色 canvas.FillRectangle(whiteBrush, 0, 0, bmp.Width, bmp.Height); //因為要由下往上畫,所以將原點設定成下方 canvas.TranslateTransform(50, bmpHeight - 200); //設定浮水印的字型及大小 Font f = new Font(DefaultFontName, fontSize, FontStyle.Bold); //設定旋轉的角度為330 canvas.RotateTransform(330); //將浮水印畫上去 canvas.DrawString(watermarks, f, watermarkBrush, fontSize, 0, StringFormat.GenericTypographic); //將圖檔輸出去 bmp.Save(context.Response.OutputStream, ImageFormat.Gif); } public bool IsReusable { get { return false; } } }
使用測試網頁試一下,底圖在網頁中間呈現,感覺還不錯。
WatermarkNoInh.aspx
<body style="background-image: url(./Pub/GetWatermark.ashx); background-repeat: no-repeat; background-color: transparent; background-position: center;"> <form id="form1" runat="server"> <div> <asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager> <asp:UpdatePanel ID="UpdatePanel1" runat="server"> <ContentTemplate> <asp:Table ID="Table1" runat="server" Width="100%"> <asp:TableRow> <asp:TableCell> <asp:Button ID="Button1" runat="server" Text="Button" /> <asp:GridView ID="GridView1" runat="server" AllowPaging="true" Width="100%"> </asp:GridView> </asp:TableCell> </asp:TableRow> </asp:Table> </ContentTemplate> </asp:UpdatePanel> </div> </form> </body>
WatermarkNoInh.aspx.CS
public partial class WatermarkNoInh : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { Session["User_Name"] = "郭小玉"; DataTable myData = new DataTable(); myData.Columns.Add("c1", typeof(int)); myData.Columns.Add("c2", typeof(string)); for (int i = 0; i < 100; i++) { myData.Rows.Add(i, i.ToString()); } GridView1.DataSource = myData; GridView1.DataBind(); } }
這時設定GridView套用Style時,發現底圖被BackColor給蓋掉了,如下,
<asp:GridView ID="GridView1" runat="server" AllowPaging="true" Width="100%" BorderColor="#3366CC" BorderStyle="None" BorderWidth="1px" CellPadding="4"> <FooterStyle BackColor="#99CCCC" ForeColor="#003399"></FooterStyle> <HeaderStyle BackColor="#003399" Font-Bold="True" ForeColor="#CCCCFF"></HeaderStyle> <PagerStyle HorizontalAlign="Left" BackColor="#99CCCC" ForeColor="#003399"></PagerStyle> </asp:GridView>
所以再Render時,再透過JQuery將所有物件的background-color設成透明的,如下,
$(document).ready(function () { $('*').css('background-color', 'transparent'); });
Q.那不就有加Style跟沒加Style一樣了嗎?
是的,不過,如果是不想改原有程式的Style,就可以這樣用!
不然就使用圖片蓋到最上面的方式(UseWatermark=2)。
Q.那如果有的網頁報表要有浮水印,有些的不要呢?
那就建立一個產生浮水印的WatermarkBasePage,然後要浮水印的Page就去繼承它(如果您原本就已經有底層的Page,就可直接把Code加在底層的Page上),程式如下(參考ASP.NET - C# Application Environment Backsplash),
public class WatermarkBasePage : System.Web.UI.Page { /// <summary> /// 是否要啟用浮水印 /// </summary> /// <remarks> /// 0:不使用浮水印 /// 1:使用底圖方式的浮水印 /// 2:使用z-index方式的浮水印 /// </remarks> public int UseWatermark { get; set; } protected override void OnPreRender(EventArgs e) { base.OnPreRender(e); switch (UseWatermark) { case 1: //要將頁面上所有物件的背景色取消掉 //這樣底圖才不會被蓋掉 ClientScript.RegisterClientScriptBlock(this.GetType(), "UseWatermark1", @" $(document).ready(function () { $('*').css('background-color', 'transparent'); if($('#imgWatermark').length==0){ $('body').prepend('<img id=""imgWatermark"" src=""./../Pub/GetWatermark.ashx?way=2"" style=""position:absolute;"" />'); } $(window).resize(); }); $(window).resize(function() { $('#imgWatermark').css('z-index', '-1').css('opacity','0.1').css('width', $('body').width()-20).css('height', $('body').height()-20); });", true); break; case 2: //使用圖片蓋到畫面上,並隨畫面調整圖片大小 ClientScript.RegisterClientScriptBlock(this.GetType(), "UseWatermark2", @" $(document).ready(function () { if($('#imgWatermark').length==0){ $('body').prepend('<img id=""imgWatermark"" src=""./../Pub/GetWatermark.ashx?way=2"" style=""position:absolute;"" />'); } $(window).resize(); }); $(window).resize(function() { $('#imgWatermark').css('z-index', '999').css('opacity','0.1').css('width', $('body').width()-20).css('height', $('body').height()-20); });", true); break; } }
在要使用的Page中繼承自WatermarkBasePage,並設定UseWatermark屬性為1或是2 (1:使用底圖方式的浮水印,2:使用z-index方式的浮水印),就會動態產生圖,並設定為該網頁的底圖。
public partial class WatermarkTest1 : WatermarkBasePage { protected void Page_Load(object sender, EventArgs e) { //要使用底圖方式的浮水印 UseWatermark = 1; Session["User_Name"] = "郭小玉"; DataTable myData = new DataTable(); myData.Columns.Add("c1", typeof(int)); myData.Columns.Add("c2", typeof(string)); for (int i = 0; i < 100; i++) { myData.Rows.Add(i, i.ToString()); } GridView1.DataSource = myData; GridView1.DataBind(); } }
public partial class WatermarkTest1 : WatermarkBasePage { protected void Page_Load(object sender, EventArgs e) { //2:使用z-index方式的浮水印 UseWatermark = 2; Session["User_Name"] = "郭小玉"; DataTable myData = new DataTable(); myData.Columns.Add("c1", typeof(int)); myData.Columns.Add("c2", typeof(string)); for (int i = 0; i < 100; i++) { myData.Rows.Add(i, i.ToString()); } GridView1.DataSource = myData; GridView1.DataBind(); } }
結論
以上提供2種浮水印方式,各Page可依需求來設定它。您也能依您的需求去調整,比如說寫浮水印的方式,可從左上到右下,或是畫個圓圈。
PS.感謝655 Fred的Support。
測試程式
Watermarks.zip 2012/09/10 改使用圖檔然後用z-Index來決定放在控制項的上面或下面。
Hi,
亂馬客Blog已移到了 「亂馬客 : Re:從零開始的軟體開發生活」
請大家繼續支持 ^_^