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));
        }



    }
}

你可能感兴趣的:(缩略图)