Hiện thị ảnh thu nhỏ (Thumbnail Image) trong Asp.Net

Xử lý hình ảnh trước khi hiển thị là việc cần thiết để tối ưu 1 website và nó giúp tăng tốc độ tải trang một cách đáng kể. Trong một số trường hợp, khi upload ảnh người ta có thể sẽ xử lý để tạo ra 1 hình ảnh thu nhỏ luôn, tuy nhiên một vấn đề gặp phải đó là không tiết kiệm dung lượng host và kích thước hình ảnh thumbnail được tạo ra không "linh động" trong các trường hợp sử dụng. Trong bài này tôi sẽ hướng dẫn các bạn tạo hình ảnh thumbail ngay trong quá trình hiển thị ảnh từ 1 file ảnh gốc duy nhất.

Để tạo hình ảnh thumbnail trong asp.net có khá nhiều cách, trong bài này tôi sẽ giới thiệu qua một số phương pháp tôi đã từng làm. Để thực hiện việc tạo ảnh thumbnail, các bạn phải sử dụng một số thư viện sau.

using System.IO;
using System.Drawing;
using System.Drawing.Imaging;

1. Sử dụng phương thức GetThumbnailImage có sẵn

- Phương thức này trả về hình ảnh dạng 1 chuỗi base64 và gán trực tiếp cho control Image. Ở file *.aspx các bạn kéo vào một Image Control như sau

<asp:Image ID="Image2" runat="server" EnableViewState="false" />

- Ở hàm load page, các bạn viết như sau

protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            string path = Server.MapPath("~/Tulips.jpg");
            System.Drawing.Image image = System.Drawing.Image.FromFile(path);
            using (System.Drawing.Image thumbnail = image.GetThumbnailImage(200, 200, new System.Drawing.Image.GetThumbnailImageAbort(ThumbnailCallback), IntPtr.Zero))
            {
                using (MemoryStream memoryStream = new MemoryStream())
                {
                    thumbnail.Save(memoryStream, ImageFormat.Png);
                    Byte[] bytes = new Byte[memoryStream.Length];
                    memoryStream.Position = 0;
                    memoryStream.Read(bytes, 0, (int)bytes.Length);
                    string base64String = Convert.ToBase64String(bytes, 0, bytes.Length);
                    Image2.ImageUrl = "data:image/png;base64," + base64String;
                    Image2.Visible = true;
                }
            }
        }
    }

    public bool ThumbnailCallback()
    {
        return false;
    }

- Hàm này bạn chỉ cần truyền vào đường dẫn hình ảnh và kích thước cần resize. Tuy nhiên với phương pháp này tôi nhận thấy chất lượng hình ảnh không được tốt, dung lượng nén không được cao. Tuy nhiên nếu ai muốn lấy đường dẫn ảnh của bạn, viewsource lên để xem chỉ có lắc đầu quay đi ^.^

<img id="Image2" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAADIC....

2. Vẽ lại ảnh thông qua một trang *.aspx

- Ở cách này, tôi tạo ra một file resizeimg.aspx có nhiệm vụ vẽ lại ảnh với các tham số như đường dẫn và kích thước truyền qua URL. Để hiển thị ảnh ta dùng như sau

<img src="resizeimg.aspx" alt="img thumbnails 2" />

- Trong code file cs của trang resizeimg.aspx như sau

protected void Page_Load(object sender, EventArgs e)
    {
        ResizeImg();
    }
    protected void ResizeImg()
    {
        try
        {
            String src = Server.MapPath("~/Tulips.jpg"); //absolute location of source image
            int thumbWidth = 200;
            int thumbHeight = 200;

            System.Drawing.Image image = System.Drawing.Image.FromFile(src);
            int srcWidth = image.Width;
            int srcHeight = image.Height;

            Bitmap bmp = new Bitmap(thumbWidth, thumbHeight);
            System.Drawing.Graphics gr = System.Drawing.Graphics.FromImage(bmp);
            gr.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
            gr.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
            gr.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;
            System.Drawing.Rectangle rectDestination = new System.Drawing.Rectangle(0, 0, thumbWidth, thumbHeight);
            gr.DrawImage(image, rectDestination, 0, 0, srcWidth, srcHeight, GraphicsUnit.Pixel);
            Response.ContentType = "image/jpeg";
            Response.Clear();
            bmp.Save(Response.OutputStream, System.Drawing.Imaging.ImageFormat.Jpeg);
            bmp.Dispose();
            Response.Flush();
            Response.End();
            bmp.Dispose();
            image.Dispose();
        }
        catch (Exception ms)
        {
            Response.Write(ms.Message);
        }
    }

- Phương pháp này có ưu điểm là tỷ lên nén ảnh rất tốt, một hình ảnh 200 x 200 pixcel dung lương chỉ khoảng 10kb, trong khi những phương pháp kia dung lượng khoảng từ gần 100kb. Tuy nhiên chất lượng hình ảnh cũng chưa thật sự tốt.

3. Tạo ảnh thumbnail bằng cách sử dụng HttpHandler

- Ở cách này, chúng ta cần tạo ra 1 file thumbnail_IMG.ashx để vẽ lại ảnh. Cách sử dụng tượng tự như đối với phương pháp 2

<img src="thumbnails_Img.ashx" alt="img thumbnails 3" />

- Trong file ashx ta viết code như sau

public void ProcessRequest (HttpContext context) {
        int W = 200;
        int H = 200;
        Image img = Image.FromFile(context.Server.MapPath("~/Tulips.jpg"));
        Image _img = new Bitmap(W, H);
        Graphics g = Graphics.FromImage(_img);
        g.DrawImage(img, 0, 0, W, H);
        g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighSpeed;
        g.Dispose();
        img.Dispose();
        MemoryStream str = new MemoryStream();
        _img = _img.GetThumbnailImage(W, H, null, IntPtr.Zero);
        _img.Save(str, System.Drawing.Imaging.ImageFormat.Png);
        _img.Dispose();
        str.WriteTo(context.Response.OutputStream);
        str.Dispose();
        str.Close();
        context.Response.ContentType = ".png";
        context.Response.End();
    }
 
    public bool IsReusable {
        get {
            return false;
        }
    }

- Ở phương pháp này, chất lượng ảnh hiển thị khá tốt, tuy nhiên tỷ lệ nén không được cao, cùng với kích thước 200 x 200 pixcel nhưng dung lượng ảnh lên đến 95kb.

4. Kết luận.

- Ở mỗi phương pháp tạo hình ảnh thumbnail hình ảnh sẽ có nhưng điểm mạnh riêng. Ví dụ với những hình ảnh hiện thì trên web với kích thước dưới 100 pixcel, các bạn nên dùng phương pháp thứ 2, với hình ảnh trong khoảng lớn hơn 100 pixcel nên dùng phương pháp thứ 3. Nếu muốn dấu nguồn ảnh, nên dùng phương pháp 1. Tuy nhiên để đàm bảo hình ảnh hiển thị sắc nét ở cả 3 phương pháp, phải chú ý resize ảnh theo đúng tỷ lệ ảnh gốc.

- Các bạn có thể download mã nguồn ví dụ ở file đính kèm để hiểu rõ hơn. Chúc các bạn thành công!

Download Source

Related Post


Tìm hiểu về ViewState trong website Asp.Net
Thursday, October 3, 2013
ViewState là một kĩ thuật giúp bạn để giữ lại trạng thái của trang mặc dù trang được Postbacks.Thường thì khi một trang được postback thì mọi giá trị trên trang sẽ không được giữ lại. Để giữ lại giá trị trên trang thì bạn phải sử dụng ViewState để lưu lại giá trị đó.    
Hiển thị ảnh xem trước khi upload trong Asp.Net
Thursday, October 3, 2013
Hiển thị ảnh xem trước do người dùng lựa chọn trước khi upload là một chức năng rất hay, thứ nhất nó thân thiện với người dùng, thứ hai đảm bảo không nhầm lẫn khi cập nhật hình ảnh. Trong bài này, ta sẽ áp dụng tính năng tiên tiến của HTML5 để thực hiện việc này
Search

Đăng ký nhận bài mới


Category

Blog Archive