2009-08-28 2 views
5

SQL Serverデータベースに格納された画像を、私がまとめて取得するユーザーデータとともに格納しています。ASP.NETの画像にbyte []をストリームするC#

今、私はそれを見せたいページに直接バイト[]を持っています。どうすればWebControls.Imageに入れることができますか?私はHttpHandlerを呼び出してデータベースを再度呼び出す必要はありません。

これは明らかにページ全体に出力します。

<img src="image.aspx?id=number" > 

番号がデータベースに

+0

画像データをファイルとして保存できませんか? – AnthonyWJones

+0

これは最初のルートでしたが、データベースにイメージを格納することが推奨されました。 (私の頭の上)だから私はその状況を最大限に活用しなければならない。 – markoo

+0

みなさん、ありがとうございます。迅速かつ洞察力のある回答。 – markoo

答えて

4

小さな画像の場合はbase64でエンコードされたデータを画像タグに出力します。 See here for a similar situation

しかし、すべての状況の99.9%で、イメージを返すHttpHandlerを作成します。それは私が考えることをする最も簡単で最速の方法です。

+0

これはまさに私が探していたものでした。画像は180 x 160ピクセルの小さなgif/jpegです。 これはこのようになりました: バイト[] picByteArray = user.Picture.ToArray(); 文字列myPicString = Convert.ToBase64String(picByteArray); myPicture.Attributes ["src"] = "data:image/gif; base64、" + myPicString; – markoo

+0

@ Markoo:base64でエンコードされたときのバイト数は何バイトですか?ダイナミックに生成されたHTMLに画像データを直接置くことで、毎回クライアントが取得する必要があります.HTMLレスポンス全体をキャッシュ可能にしない限り、キャッシュ可能ではありません。 – AnthonyWJones

+0

私のイメージは約8KBになります。これは私の単純なユーザーデータビューではかなり受け入れられます。私の会社内の「内部」管理サイトです。実際のコンポーネントは外部で使用されますが。これらの外部コンポーネントとサイトは管理者によって大量にキャッシュされています。だから、私はこのソリューションを実装する上で心配はありません。 これらのプロファイルは非常に限定されています。自宅のジャーナリストで約20人か30人しかいない。だから、ちょうどこれらのために別々のイメージテーブルを持っているのは残酷なようでした。 もう一度あなたの洞察力に感謝します。 – markoo

0

により、たとえば画像を作成する別のページを作成しますMemoryStreamオブジェクトに格納し、ASP.NETsキャッシュに配置します。

MemoryStream ms = new MemoryStream(user.Picture.ToArray()); 
Guid imageGuid = new Guid(); 
HttpRuntime.Cache.Add(imageGuid.ToString(), ms, null, 
    DateTime.Now.AddMinutes(5), Cache.NoSlidingExpiration, CacheItemPriority.Normal, null); 

次に、ハンドラ(.ashx)を使用してキャッシュからフェッチし、クライアントに送信します。

string imageGuid = context.Request.QueryString[image]; 
MemoryStream ms = (MemoryStream)HttpRuntime.Cache[imageGuid]; 
// configure context.Response with appropriate content type and cache settings 

// ** Edit ** 
// It seems I need to be more explicit with regard to the above comment:- 
context.Response.Cache.SetCacheability(HttpCacheability.Public); 
context.Response.Cache.SetLastModified(DateTime.UtcNow); 
context.Response.Cache.SetExpires(DateTime.UtcNow.AddHours(2); 
context.Response.Cache.SetMaxAge(TimeSpan.FromHours(2)); 
context.Response.Cache.SetValidUntilExpires(true); 

ms.WriteTo(context.Response.OutputStream); 

これで、キャッシュからMemoryStreamを削除できます。

HttpRuntime.Cache.Remove(imageGuid); 
+0

ASPXを使用して画像を出力しないでください。ashxを使用してください。 – AnthonyWJones

+0

@Anthony:OPは、「ashx」を使いたくないと言っていますが、これを行うのが正しい方法だと私は同意します。 (そして、 'aspx'を作ることは、とにかく' ashx'を作るより簡単ではありません!) – LukeH

+0

@Anthony:私は別のことを知りません。それは唯一の拡張子ですか?それはルーティングと偶数number.jpgすることができます。 –

1

ラップバイト配列画像のIDですimage.aspx や他のページにそれを使用する:

  Context.Response.BinaryWrite(user.Picture.ToArray()); 
+0

これはWebファーム全体で縮尺変更されません(分散キャッシュを使用していない限り)。 – LukeH

+0

決してこれを行うことはありません。 HTTP( 'If-Modified-Since'、キャッシングなど)とスケーラビリティの恩恵を全く犠牲にしているわけではありません。 –

+0

@anton:コード内にコメント行がありますか?私はそれが何を意味すると思いますか? – AnthonyWJones

0

あなたは応答ストリームに画像バイト、適切Content-Typeを書き込みますIHttpHanderを必要としています。 this,thisおよびthisを参照のこと。

+0

あなたは質問のポイントを逃しました。実行中のASPXページにデータベースから取得したイメージデータのバイト配列があると、DBに再クエリを行わずにそのイメージを表示するために出力でどのように ' AnthonyWJones

+0

@Anthony:確かに、彼は、ページ自体のデータベースから画像データを取り出す必要はありません。彼は*データベースを再クエリする必要はありません - 適切な場所/時間(つまり、別の 'ashx'ハンドラ)で*一度問い合わせる必要があります。 – LukeH

+0

@ルーク:そうかもしれませんが、私たちはそれを知らないのですか?私たちは、何らかの理由で、彼はすでに読み込まれたPictureオブジェクトを持っているオブジェクトを持っています。ファイルシステムに画像を置いたほうが良いかもしれません。私は特に、他のSOユーザがやむを得ない理由でこの状況にいることがあるかもしれないので、手元の質問に答えることを好む。 – AnthonyWJones

0

私はあなたがページ自体でこれを行うことはできないと確信しています。

HTTPハンドラを作成してイメージを出力したくない場合は、別のaspxページを作成することもできます。 imgタグのsrcをそのページを指すように設定し、クエリー文字列にある種のIDを渡して、イメージデータをデータベースから取得できるようにします。

これを行うには、aspxページを設定することは、ashxを設定するよりも速く簡単です。私はこれを行うことをお勧めします方法とHTTPハンドラを作成します。

+0

私は既にデータベースのデータを持っています。私は別の呼び出しを保存したい。 – markoo

関連する問題