2008-08-22 35 views
13

Điều tôi muốn đạt được là điều này. Tôi muốn cung cấp cho người dùng khả năng tải lên tệp hình ảnh, lưu trữ hình ảnh trong BLOB trong SQL Server và sau đó sử dụng hình ảnh này làm biểu tượng ở các trang khác của trang web.Hiển thị động asp: Hình ảnh từ mục nhập BLOB trong ASP.NET

Tôi đã làm điều này bằng cách sử dụng

Response.Clear(); 
    Response.ContentType = "image/pjpeg"; 
    Response.BinaryWrite(imageConents); 
    Response.End(); 

nhưng để làm được điều này, tôi sử dụng một điều khiển người dùng trong nơi mà tôi muốn thể hiện hình ảnh. Tôi muốn làm điều đó nếu có thể bằng cách sử dụng một asp: Kiểm soát hình ảnh, hoặc thậm chí là một điều khiển hình ảnh html cũ thuần túy. Điều này có thể không?

Cảm ơn tất cả

+0

Nếu bạn đang làm việc với System.Drawing trong ASP.NET, [đọc những cạm bẫy bạn cần phải tránh] (http://nathanaeljones.com/163/20-image-resizing-pitfalls/). Ngoài ra, chỉ cần sử dụng thư viện [my ImageResizing.Net] (http://imageresizing.net) để tránh tất cả các lỗi GDI, có được trình đọc SQL Blob được tối ưu hóa và hệ thống lưu trữ bộ nhớ đệm cực tốt. –

+1

Bài viết sau sẽ giúp bạn: [Tự động liên kết byte [] thành asp: Hình ảnh] (http://www.codeproject.com/Tips/445876/Auto-bind-byte-to-asp-Image) –

Trả lời

18

Thêm 'Trình xử lý chung' vào dự án web của bạn, đặt tên nó là Image.ashx. Thực hiện nó như thế này:

public class ImageHandler : IHttpHandler 
{ 

    public void ProcessRequest(HttpContext context) 
    { 
     using(Image image = GetImage(context.Request.QueryString["ID"])) 
     {  
      context.Response.ContentType = "image/jpeg"; 
      image.Save(context.Response.OutputStream, ImageFormat.Jpeg); 
     } 
    } 

    public bool IsReusable 
    { 
     get 
     { 
      return true; 
     } 
    } 
} 

Bây giờ chỉ cần thực hiện các phương pháp GetImage để tải hình ảnh với ID nhất định, và bạn có thể sử dụng

<asp:Image runat="server" ImageUrl="~/Image.ashx?ID=myImageId" /> 

để hiển thị nó. Bạn có thể muốn suy nghĩ về việc thực hiện một số hình thức bộ nhớ đệm trong trình xử lý. Và hãy nhớ nếu bạn muốn thay đổi định dạng hình ảnh thành PNG, bạn cần phải sử dụng MemoryStream trung gian (vì PNG yêu cầu phải lưu luồng tìm kiếm được).

+0

Tôi biết điều này là cũ, nhưng tôi nghĩ rằng bạn có những gì tôi đang tìm kiếm ở đây. Tôi chỉ thiếu kiến ​​thức ngay bây giờ, để tìm ra. Tôi đã được xử lý bằng văn bản. Đây là http://pastebin.com/m75e17237 và tôi đã nhận được cuộc gọi đến trình xử lý đó. Có vẻ như sau: http://pastebin.com/m63e1ebc3 Nhưng khi tải trang, tôi chỉ nhận được hình ảnh thiếu màu đỏ X hộp. Tôi chưa bao giờ sử dụng trình xử lý trước đây, vì vậy có thể làm điều gì đó sai. Một điều tôi nhận thấy là nếu tôi đặt một điểm ngắt trong trình xử lý, nó sẽ không bao giờ đến đó. Mọi lời khuyên sẽ thật tuyệt vời, nếu bạn có cơ hội. -Will – aape

+0

@aape: bạn đã đăng ký trình xử lý trong web.config chưa? –

+0

Đang cố gắng nhận câu trả lời cho vấn đề của tôi ở đây, tôi có hai hình ảnh mà tôi muốn hiển thị trên chế độ xem tùy thuộc vào việc học sinh có đăng ký hay không, chế độ xem này tôi đã nhập mạnh mẽ, làm cách nào để làm việc này? – user793468

9

Bạn có thể BASE64 mã hóa nội dung của hình ảnh trực tiếp vào thuộc tính SRC, tuy nhiên, tôi tin rằng chỉ Firefox sẽ phân tích cú pháp này thành hình ảnh.

Những gì tôi thường làm là một tạo một HTTPHandler rất nhẹ để phục vụ những hình ảnh:

using System; 
using System.Web; 

namespace Example 
{ 
    public class GetImage : IHttpHandler 
    { 

     public void ProcessRequest(HttpContext context) 
     { 
      if (context.Request.QueryString("id") != null) 
      { 
       Blob = GetBlobFromDataBase(id); 
       context.Response.Clear(); 
       context.Response.ContentType = "image/pjpeg"; 
       context.Response.BinaryWrite(Blob); 
       context.Response.End(); 
      } 
     } 

     public bool IsReusable 
     { 
      get 
      { 
       return false; 
      } 
     } 
    } 
} 

Bạn có thể tham khảo này trực tiếp trong thẻ img của bạn:

<img src="GetImage.ashx?id=111"/> 

Hoặc, bạn thậm chí có thể tạo ra điều khiển máy chủ thực hiện điều đó cho bạn:

using System; 
using System.Web; 
using System.Web.UI; 
using System.Web.UI.WebControls; 

namespace Example.WebControl 
{ 

    [ToolboxData("<{0}:DatabaseImage runat=server></{0}:DatabaseImage>")] 
    public class DatabaseImage : Control 
    { 

     public int DatabaseId 
     { 
      get 
      { 
       if (ViewState["DatabaseId" + this.ID] == null) 
        return 0; 
       else 
        return ViewState["DataBaseId"]; 
      } 
      set 
      { 
       ViewState["DatabaseId" + this.ID] = value; 
      } 
     } 

     protected override void RenderContents(HtmlTextWriter output) 
     { 
      output.Write("<img src='getImage.ashx?id=" + this.DatabaseId + "'/>"); 
      base.RenderContents(output); 
     } 
    } 
} 

Điều này có thể được sử dụng như

<cc:DatabaseImage id="db1" DatabaseId="123" runat="server/> 

Và tất nhiên, bạn có thể đặt cơ sở dữ liệuId trong codebehind nếu cần.

+0

Thế nào là hình ảnh/pjpeg? Đó là một lỗi trong IE, không phải là một loại mime hợp lệ được sử dụng trên máy chủ;) –

0

Thêm mã vào trình xử lý để trả về byte hình ảnh có loại mime phù hợp. Sau đó, bạn chỉ có thể thêm url vào trình xử lý của mình như là một hình ảnh. Ví dụ:

<img src="myhandler.ashx?imageid=5"> 

Có ý nghĩa?

5

Bạn không muốn phục vụ các đốm màu từ cơ sở dữ liệu mà không triển khai bộ đệm ẩn phía máy khách.

Bạn sẽ cần phải xử lý các tiêu đề sau đây để hỗ trợ phía khách hàng bộ nhớ đệm:

  • ETag
  • Expires
  • Last Modified
  • If-Match
  • Nếu-Không-Khớp
  • Nếu được sửa đổi từ
  • Nếu chưa sửa đổi từ
  • Trừ-Modified-Since

Đối với một handler http rằng thực hiện điều này, hãy kiểm tra: http://code.google.com/p/talifun-web/wiki/StaticFileHandler

Nó có một helper tốt đẹp để cung cấp nội dung. Nó sẽ được dễ dàng để vượt qua trong dòng cơ sở dữ liệu với nó. Nó cũng làm bộ nhớ đệm phía máy chủ mà sẽ giúp giảm bớt một số áp lực trên cơ sở dữ liệu.

Nếu bạn quyết định phân phát nội dung trực tuyến từ cơ sở dữ liệu, tệp pdf hoặc tệp lớn, trình xử lý cũng hỗ trợ 206 yêu cầu một phần.

Nó cũng hỗ trợ gzip và giảm kích thước nén.

Những loại tập tin sẽ được hưởng lợi từ nén thêm:

  • css, js, htm, html, swf, XML, XSLT, txt
  • doc, xls, ppt

Có một số loại tệp sẽ không được hưởng lợi từ việc nén tiếp theo:

  • pdf (gây ra sự cố với các phiên bản nhất định trong IE và nó là usu đồng minh cũng nén)
  • png, jpg, jpeg, gif, ico
  • wav, mp3, m4a, aac (wav thường được nén)
  • 3gp, 3g2, asf, avi, dv, flv, mov, mp4 , mpg, mpeg, wmv
  • zip, rar, 7z, arj
+0

Wow! Câu hỏi này đã hơn một năm! Cảm ơn câu trả lời, tuy nhiên tôi đã giải quyết vấn đề! 1 cho câu trả lời tài liệu tốt. –

+0

Ngoài ra, bạn có thể cache vào đĩa và cho phép IIS xử lý ETag, Last-Modified, vv Giống như [ImageResizing.net] (http://imageresizing.net). IIS có một lợi thế hiệu suất tốt hơn mã được quản lý để phục vụ các tệp tĩnh, ngay cả với việc triển khai .NET tối ưu. –

+0

Đó là lý do tại sao tôi xử lý ngoại tuyến và theo cách có thể mở rộng. https://github.com/taliesins/talifun-commander – Taliesin

2

Sử dụng ASP.Net với MVC này là khá mong dễ dàng. Bạn viết mã một bộ điều khiển với một phương pháp như thế này:

public FileContentResult Image(int id) 
{ 
    //Get data from database. The Image BLOB is return like byte[] 
    SomeLogic ItemsDB= new SomeLogic("[ImageId]=" + id.ToString()); 
    FileContentResult MyImage = null; 
    if (ItemsDB.Count > 0) 
    { 
     MyImage= new FileContentResult(ItemsDB.Image, "image/jpg"); 
    } 

    return MyImage; 
} 

Trong ASP.NET của bạn Web Xem hoặc trong ví dụ này, trong Web Form ASP.NET của bạn, bạn có thể điền vào một điều khiển hình ảnh với các URL để phương pháp của bạn như thế này :

  this.imgExample.ImageUrl = "~/Items/Image/" + MyItem.Id.ToString(); 
      this.imgExample.Height = new Unit(120); 
      this.imgExample.Width = new Unit(120); 

Voilá. Không HttpModules rắc rối là cần thiết.

Các vấn đề liên quan