程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> 關於C# >> C#生成縮略圖控件

C#生成縮略圖控件

編輯:關於C#

實現原理:

1、我們現在要做的是自定義Web控件,這和平常設計aspx網頁或者用戶控件有本質區別,自定義控件 是一個派生自System.Web.WebControls.WebControl的類,它是一個類,而不是你想象中的HTML代碼,甚 至在自定義控件中你完全找不到HTMl的任何風格。因此,你必須對類的編寫設計非常數量,或者是,跳出 設計HTML的圈子,拓展思維!

2、我們要實現不依靠文件系統、不依靠額外的任何其他東西,僅僅依靠一個類來實現它,這樣做好處 自然明顯——各位只要復制得下面的一堆代碼,自己建一個cs文件放進去就可以編譯(編譯為dll)。所 有功能都是自含的,除了位於公共位置的.net類庫,其他任何dll我都不需要引用。

然而,要實現如第2條這樣的效果,我們得把對縮略圖的請求設計成為對包含控件網頁本身的請求,因 為針對縮略圖的這一次請求,本質仍然對本網頁的請求,這樣,網頁中包含的縮略圖控件才有機會操縱流 。當然,兩次請求都針對同一張網頁的話,我們要設法區分開,哪一次是真正請求網頁的原內容,哪一次 是針對請求一個縮略圖。

不知上述這段話大家能否理解,

如果不這樣做的話,我們就不得不需要額外的控件或網頁來實行了。

看懂了上述原理,我現在把流程寫在下面,就自然好理解了:

1、客戶請求一張網頁,如index.aspx,網頁中含有縮略圖控件,

2、Index.aspx編譯執行為HTML後被發送到客戶端浏覽器。這個控件生成了一個img標記,src屬性指向 一張該網頁本身,但是後面附帶的參數改變了。浏覽器解析了,知道要向src屬性獲得一張圖片。它開始 向這個位置請求(也就是重新以新的附帶參數請求這個網頁)。

3、ASP.Net獲得了這個請求,index.aspx這個頁面又開始執行,因為index.aspx中包含這個縮略圖控 件,控件就有機會識別這段特殊的參數,並且重新改寫響應流,它會在文件系統中獲得原始圖像,然後根 據你的要求,使用GDI.NET將原圖重新按照新尺寸繪制,得到的新圖是一個流對象,我們不存儲它,而是 將它直接附著在響應流中,發送給客戶端。

4、客戶端浏覽器得到這張圖片。網頁加載完成。

好,原理是說了不少,雖然我盡量寫得通俗,但難免大家一時半會兒可能不好理解。那我現在就把代 碼貼出來讓大家參考。

這個縮略圖控件還沒有添加水印等類似版權保護的功能,各位有興趣的高手不妨完善一下這部分內容 。同時與各位朋友相互學習,加強思考,增進思維。我們不管ASP.NET孰優孰劣,對於個人來說,既然追 隨ASP.NET,就要把ASP.NET用好,隨波逐流的程序員永遠不會優秀。

using System;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Drawing;
using System.ComponentModel;
using System.Drawing.Design;
using System.Drawing.Drawing2D;
using System.Text;
using System.IO;

namespace BlogLan.Web.Controls
{
    /// <summary>
    /// 縮略圖控件。
    /// </summary>
    [DefaultProperty("ImageUrl")]
    [ToolboxData("<{0}:Thumbnail runat=server></{0}:Thumbnail>")]
    [DesignerAttribute(typeof(Designer.ThumbnailDesigner))]
    [Description("縮略圖控件。")]
    public class Thumbnail : WebControl
    {
        public Thumbnail()
            : base(HtmlTextWriterTag.Img)
        {
            this.Width = Unit.Parse("100");
            this.Height = Unit.Parse("75");
        }

        //Private Members
        private bool urlResolved;

        /// <summary>
        /// 獲取或設置圖片路徑。
        /// </summary>
        [Editor("System.Web.UI.Design.ImageUrlEditor, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", typeof(UITypeEditor)), Description("獲取或設置圖片路徑"), Bindable(true), Category("Appearance"), DefaultValue(""), UrlProperty]
        public string ImageUrl
        {
            get
            {
                if (this.ViewState["ImageUrl"] != null)
                {
                    return (string)this.ViewState["ImageUrl"];
                }
                return string.Empty;
            }
            set
            {
                this.ViewState["ImageUrl"] = value;
            }
        }

        /// <summary>
        /// 獲取或設置Jpeg縮略圖的質量,值范圍-100。
        /// </summary>
        [DefaultValue(80)]
        public int JpegQuality
        {
            get
            {
                if (this.ViewState["JpegQuility"] != null)
                {
                    return (int)this.ViewState["JpegQuility"];
                }
                return 80;
            }
            set
            {
                if (value > 100)
                {
                    this.ViewState["JpegQuility"] = 100;
                }
                else if (value < 20)
                {
                    this.ViewState["JpegQuility"] = 20;
                }
                else
                {
                    this.ViewState["JpegQuility"] = value;
                }
            }
        }

        [DefaultValue(typeof(Unit), "100px")]
        public override Unit Width
        {
            get
            {
                return base.Width;
            }
            set
            {
                base.Width = value;
            }
        }

        [DefaultValue(typeof(Unit), "75px")]
        public override Unit Height
        {
            get
            {
                return base.Height;
            }
            set
            {
                base.Height = value;
            }
        }

        internal bool UrlResolved
        {
            get
            {
                return this.urlResolved;
            }
            set
            {
                this.urlResolved = value;
            }
        }

        /// <summary>
        /// 獲取或設置控件相對於網頁上其他元素的對齊方式。
        /// </summary>
        [DefaultValue(ImageAlign.NotSet), Description("獲取或設置控件相對於網頁上其 他元素的對齊方式。")]
        public virtual ImageAlign ImageAlign
        {
            get
            {
                object obj2 = this.ViewState["ImageAlign"];
                if (obj2 != null)
                {
                    return (ImageAlign)obj2;
                }
                return ImageAlign.NotSet;
            }
            set
            {
                if ((value < ImageAlign.NotSet) || (value > ImageAlign.TextTop))
                {
                    throw new ArgumentOutOfRangeException("value");
                }
                this.ViewState["ImageAlign"] = value;
            }
        }

        /// <summary>
        /// [禁用Enabled屬性在任何位置編輯。]
        /// </summary>
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        public override bool Enabled
        {
            get
            {
                return base.Enabled;
            }
            set
            {
                base.Enabled = value;
            }
        }

        /// <summary>
        /// 如無法顯示圖片時顯示的替代文本。
        /// </summary>
        [DefaultValue(""), Bindable(true), Localizable(true), Description("如無法顯 示圖片時顯示的替代文本。")]
        public virtual string AlternateText
        {
            get
            {
                if (this.ViewState["AlternateText"] != null)
                {
                    return (string)this.ViewState["AlternateText"];
                }
                return string.Empty;
            }
            set
            {
                this.ViewState["AlternateText"] = value;
            }
        }

        /// <summary>
        /// 獲取或設置一個值,該值指示控件是否生成空字符串值的替換文字屬性。
        /// </summary>
        [DefaultValue(true), Description("獲取或設置一個值,該值指示控件是否生成空 字符串值的替換文字屬性。")]
        public virtual bool GenerateEmptyAlternateText
        {
            get
            {
                if (this.ViewState["GenerateEmptyAlternateText"] != null)
                {
                    return (bool)this.ViewState ["GenerateEmptyAlternateText"];
                }
                return true;
            }
            set
            {
                this.ViewState["GenerateEmptyAlternateText"] = value;
            }
        }

        /// <summary>
        /// 獲取或設置圖像詳細說明的位置。
        /// </summary>
        [Editor("System.Web.UI.Design.UrlEditor, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", typeof(UITypeEditor)), UrlProperty, DefaultValue(""), Description("獲取或設置圖像詳細說明的位置。")]
        public virtual string DescriptionUrl
        {
            get
            {
                string str = (string)this.ViewState["DescriptionUrl"];
                if (str != null)
                {
                    return str;
                }
                return string.Empty;
            }
            set
            {
                this.ViewState["DescriptionUrl"] = value;
            }
        }

        //Methods

        /// <summary>
        /// 重寫AddAttributesToRender方法。
        /// </summary>
        /// <param name="writer"></param>
        protected override void AddAttributesToRender(HtmlTextWriter writer)
        {
            if (string.IsNullOrEmpty(this.Page.Request["thumbnail"]))
            {
                this.AddThumbnailAttributesToRender(writer, string.Empty);
            }
        }

        protected virtual internal void AddThumbnailAttributesToRender (HtmlTextWriter writer, string ForcedImageUrl)
        {
            base.AddAttributesToRender(writer);
            string imageUrl = this.ImageUrl;

            if (!this.UrlResolved)
            {
                imageUrl = base.ResolveClientUrl(imageUrl);
            }

            //在設計時強制賦予圖形路徑。
            if (!string.IsNullOrEmpty(ForcedImageUrl))
            {
                imageUrl = ForcedImageUrl;
                writer.AddAttribute(HtmlTextWriterAttribute.Src, imageUrl);
            }
            else
            {
                writer.AddAttribute(HtmlTextWriterAttribute.Src, this.Page.Request.Url.AbsolutePath + "?" + this.GetQueryString(), false);
            }


            imageUrl = this.DescriptionUrl;
            if (imageUrl.Length != 0)
            {
                writer.AddAttribute(HtmlTextWriterAttribute.Longdesc, base.ResolveClientUrl(imageUrl));
            }
            imageUrl = this.AlternateText;
            if ((imageUrl.Length > 0) || this.GenerateEmptyAlternateText)
            {
                writer.AddAttribute(HtmlTextWriterAttribute.Alt, imageUrl);
            }
            switch (this.ImageAlign)
            {
                case ImageAlign.Left:
                    writer.AddAttribute(HtmlTextWriterAttribute.Align, "left");
                    break;

                case ImageAlign.Right:
                    writer.AddAttribute(HtmlTextWriterAttribute.Align, "right");
                    break;

                case ImageAlign.Baseline:
                    writer.AddAttribute(HtmlTextWriterAttribute.Align, "baseline");
                    break;

                case ImageAlign.Top:
                    writer.AddAttribute(HtmlTextWriterAttribute.Align, "top");
                    break;

                case ImageAlign.Middle:
                    writer.AddAttribute(HtmlTextWriterAttribute.Align, "middle");
                    break;

                case ImageAlign.Bottom:
                    writer.AddAttribute(HtmlTextWriterAttribute.Align, "bottom");
                    break;

                case ImageAlign.AbsBottom:
                    writer.AddAttribute(HtmlTextWriterAttribute.Align, "absbottom");
                    break;

                case ImageAlign.AbsMiddle:
                    writer.AddAttribute(HtmlTextWriterAttribute.Align, "absmiddle");
                    break;

                case ImageAlign.NotSet:
                    break;

                default:
                    writer.AddAttribute(HtmlTextWriterAttribute.Align, "texttop");
                    break;
            }

            if (this.BorderWidth.IsEmpty)
            {
                writer.AddStyleAttribute(HtmlTextWriterStyle.BorderWidth, "0px");
            }
        }

        private string GetQueryString()
        {
            StringBuilder sb = new StringBuilder();
            sb.Append("thumbnail=" + this.Page.Server.HtmlEncode (this.ImageUrl));
            sb.Append("&w=" + this.Width.Value.ToString());
            sb.Append("&h=" + this.Height.Value.ToString());
            sb.Append("&bc=" + this.BackColor.ToArgb().ToString());
            sb.Append("&jq=" + this.JpegQuality.ToString());

            return sb.ToString();
        }

        protected override void RenderContents(HtmlTextWriter writer)
        {
        }

        protected override ControlCollection CreateControlCollection()
        {
            return new EmptyControlCollection(this);
        }

        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);
            this.Init += new EventHandler(Thumbnail_Init);
            this.PreRender += new EventHandler(Thumbnail_PreRender);
        }

        void Thumbnail_PreRender(object sender, EventArgs e)
        {
            if (HttpContext.Current != null)
            {
                RenderThumbnailImage(this.Page.Request, this.Page.Response);
            }
        }

        void Thumbnail_Init(object sender, EventArgs e)
        {
            if (HttpContext.Current != null)
            {
                RenderThumbnailImage(this.Page.Request, this.Page.Response);
            }
        }

        static void RenderThumbnailImage(HttpRequest request, HttpResponse response)
        {
            if (string.IsNullOrEmpty(request["thumbnail"]))
            {
                return;
            }

            Thumbnail thumbnail = new Thumbnail();

            Bitmap tmb;
            try
            {
                thumbnail.ImageUrl = request["thumbnail"];

                try
                {
                    thumbnail.Width = Unit.Parse(request["w"]);
                }
                catch
                {
                    thumbnail.Width = Unit.Pixel(100);
                }

                try
                {
                    thumbnail.Height = Unit.Parse(request["h"]);
                }
                catch
                {
                    thumbnail.Height = Unit.Pixel(75);
                }
                try
                {
                    thumbnail.BackColor = Color.FromArgb (Convert.ToInt32(request["bc"]));
                }
                catch
                {
                    thumbnail.BackColor = Color.Black;
                }
                try
                {
                    thumbnail.JpegQuality = Convert.ToInt32(request ["jq"]);
                }
                catch
                {
                    thumbnail.JpegQuality = 80;
                }

                tmb = thumbnail.GetThumbnail();
            }
            catch
            {
                tmb = Properties.Resources.GenerateImageError;
            }

            response.Clear();
            string[] ImageFilePart = thumbnail.ImageUrl.ToLower().Split ('.');
            string Suffix = "bmp";
            if (ImageFilePart.Length > 1)
            {
                Suffix = ImageFilePart[ImageFilePart.Length - 1];
            }

            if (Suffix == "gif")
            {
                response.ContentType = "image/gif";
                tmb.Save(response.OutputStream, System.Drawing.Imaging.ImageFormat.Gif);
            }
            else if (Suffix == "jpg" || Suffix == "jpeg")
            {
                response.ContentType = "image/jpeg";

                System.Drawing.Imaging.EncoderParameters encoderParams = new System.Drawing.Imaging.EncoderParameters();
                long[] quality = new long[] { Convert.ToInt64 (thumbnail.JpegQuality) };
                System.Drawing.Imaging.EncoderParameter encoderParam = new System.Drawing.Imaging.EncoderParameter(System.Drawing.Imaging.Encoder.Quality, quality);
                encoderParams.Param[0] = encoderParam;
                System.Drawing.Imaging.ImageCodecInfo[] arrayICI = System.Drawing.Imaging.ImageCodecInfo.GetImageEncoders();
                System.Drawing.Imaging.ImageCodecInfo jpegICI = null;
                for (int fwd = 0; fwd < arrayICI.Length - 1; fwd++)
                {
                    if (arrayICI[fwd].FormatDescription.Equals ("JPEG"))
                    {
                        jpegICI = arrayICI[fwd];
                        break;
                    }
                }

                if (jpegICI != null)
                {
                    tmb.Save(response.OutputStream, jpegICI, encoderParams);
                }
                else
                {
                    tmb.Save(response.OutputStream, System.Drawing.Imaging.ImageFormat.Jpeg);
                }

            }
            else
            {
                response.ContentType = "image/bmp";
                tmb.Save(response.OutputStream, System.Drawing.Imaging.ImageFormat.Bmp);
            }

            tmb.Dispose();

            response.Flush();

        }

        //

        public Bitmap GetThumbnail()
        {
            return this.GetThumbnail(this);
        }

        private Bitmap GetThumbnail(Thumbnail thumbnail)
        {
            if (thumbnail == null)
                return Properties.Resources.GenerateImageError;

            System.Drawing.Image OriginalImage;
            try
            {
                if (thumbnail.DesignMode)
                {
                    //string pagepath = thumbnail.MapPathSecure ("/");
                    OriginalImage = (System.Drawing.Image) Properties.Resources.ThumbnailDesign;

                }
                else
                {
                    OriginalImage = System.Drawing.Image.FromFile (thumbnail.Context.Server.MapPath(thumbnail.ImageUrl));
                }
            }
            catch
            {
                return Properties.Resources.GenerateImageError;
            }

            Size thumbnailNewSize = this.GetNewSize(Convert.ToInt32 (thumbnail.Width.Value), Convert.ToInt32(thumbnail.Height.Value), OriginalImage.Width, OriginalImage.Height);

            Bitmap outbmp = new Bitmap(Convert.ToInt32(thumbnail.Width.Value), Convert.ToInt32(thumbnail.Height.Value));
            Graphics g = Graphics.FromImage(outbmp);
            try
            {
                g.CompositingQuality = CompositingQuality.HighQuality;
                g.SmoothingMode = SmoothingMode.HighQuality;
                g.InterpolationMode = InterpolationMode.HighQualityBicubic;

                g.Clear(thumbnail.BackColor);

                Rectangle _Vb_t_record_0 = new Rectangle((int)Math.Round ((double)(((double)(thumbnail.Width.Value - thumbnailNewSize.Width)) / 2.0)), (int) Math.Round((double)(((double)(thumbnail.Height.Value - thumbnailNewSize.Height)) / 2.0)), thumbnailNewSize.Width, thumbnailNewSize.Height);
                g.DrawImage(OriginalImage, _Vb_t_record_0, 0, 0, OriginalImage.Width, OriginalImage.Height, GraphicsUnit.Pixel);
                g.Dispose();
            }
            catch
            {
                return Properties.Resources.GenerateImageError;
            }
            finally
            {
                g.Dispose();
                OriginalImage.Dispose();
            }

            return outbmp;

        }

        private Size GetNewSize(int maxWidth, int maxHeight, int width, int height)
        {
            double w = 0.0;
            double h = 0.0;
            double sw = Convert.ToDouble(width);
            double sh = Convert.ToDouble(height);
            double mw = Convert.ToDouble(maxWidth);
            double mh = Convert.ToDouble(maxHeight);
            if ((sw < mw) & (sh < mh))
            {
                w = sw;
                h = sh;
            }
            else if ((sw / sh) > (mw / mh))
            {
                w = maxWidth;
                h = (w * sh) / sw;
            }
            else
            {
                h = maxHeight;
                w = (h * sw) / sh;
            }
            return new Size(Convert.ToInt32(w), Convert.ToInt32(h));
        }
    }
}

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved