ページに表示したいバイト配列の画像ファイルを持つモデルがあります。
データベースに戻らずにそれを行うにはどうすればよいですか?
私が見るすべてのソリューションはActionResult
、データベースに戻って画像を取得するために使用しますが、モデルには既に画像があります...
ページに表示したいバイト配列の画像ファイルを持つモデルがあります。
データベースに戻らずにそれを行うにはどうすればよいですか?
私が見るすべてのソリューションはActionResult
、データベースに戻って画像を取得するために使用しますが、モデルには既に画像があります...
これは私のために働いた
<img src="data:image;base64,@System.Convert.ToBase64String(Model.CategoryPicture.Content)" width="80" height="80"/>
画像がモデルの内部にある場合でも、これらの線に沿ったものをお勧めします.
ビューから直接アクセスする方法を求めていることを認識しています.他の多くの人がそれに答えて、そのアプローチの何が問題なのかを教えてくれました.より良いアプローチだと思います。
サンプル モデル:
[Bind(Exclude = "ID")]
public class Item
{
[Key]
[ScaffoldColumn(false)]
public int ID { get; set; }
public String Name { get; set; }
public byte[] InternalImage { get; set; } //Stored as byte array in the database.
}
コントローラのサンプル メソッド:
public async Task<ActionResult> RenderImage(int id)
{
Item item = await db.Items.FindAsync(id);
byte[] photoBack = item.InternalImage;
return File(photoBack, "image/png");
}
意見
@model YourNameSpace.Models.Item
@{
ViewBag.Title = "Details";
}
<h2>Details</h2>
<div>
<h4>Item</h4>
<hr />
<dl class="dl-horizontal">
<img src="@Url.Action("RenderImage", new { id = Model.ID})" />
</dl>
<dl class="dl-horizontal">
<dt>
@Html.DisplayNameFor(model => model.Name)
</dt>
<dd>
@Html.DisplayFor(model => model.Name)
</dd>
</dl>
</div>
画像がそれほど大きくない場合、および画像を頻繁に再利用する可能性が高い場合、および画像の数が多すぎない場合、および画像が秘密ではない場合 (サイズが大きくないことを意味します)あるユーザーが別の人の画像を見る可能性がある場合に対処します)...
ここにはたくさんの「if」があるので、これは悪い考えである可能性が高いです:
画像バイトをCache
短時間保存し、アクション メソッドを指す画像タグを作成できます。アクション メソッドはキャッシュから読み取り、画像を吐き出します。これにより、ブラウザは画像を適切にキャッシュできます。
// In your original controller action
HttpContext.Cache.Add("image-" + model.Id, model.ImageBytes, null,
Cache.NoAbsoluteExpiration, TimeSpan.FromMinutes(1),
CacheItemPriority.Normal, null);
// In your view:
<img src="@Url.Action("GetImage", "MyControllerName", new{fooId = Model.Id})">
// In your controller:
[OutputCache(VaryByParam = "fooId", Duration = 60)]
public ActionResult GetImage(int fooId) {
// Make sure you check for null as appropriate, re-pull from DB, etc.
return File((byte[])HttpContext.Cache["image-" + fooId], "image/gif");
}
これには、インライン画像が IE7 (または 32kB を超える場合は IE8) では機能しない古いブラウザーで動作するという追加の利点があります (または松葉杖ですか?)。
これは、私がプロジェクトで使用する Manoj の回答の修正版です。クラス、html 属性を取り、TagBuilder を使用するように更新されました。
public static IHtmlString Image(this HtmlHelper helper, byte[] image, string imgclass,
object htmlAttributes = null)
{
var builder = new TagBuilder("img");
builder.MergeAttribute("class", imgclass);
builder.MergeAttributes(new RouteValueDictionary(htmlAttributes));
var imageString = image != null ? Convert.ToBase64String(image) : "";
var img = string.Format("data:image/jpg;base64,{0}", imageString);
builder.MergeAttribute("src", img);
return MvcHtmlString.Create(builder.ToString(TagRenderMode.SelfClosing));
}
次のように使用できます。
@Html.Image(Model.Image, "img-cls", new { width="200", height="200" })
以下の回答に基づいてヘルパー メソッドを作成しました。このヘルパーができるだけ多くの人を助けることができることを非常にうれしく思います。
モデルの場合:
public class Images
{
[Key]
public int ImagesId { get; set; }
[DisplayName("Image")]
public Byte[] Pic1 { get; set; }
}
ヘルパーは次のとおりです。
public static IHtmlString GetBytes<TModel, TValue>(this HtmlHelper<TModel> helper, System.Linq.Expressions.Expression<Func<TModel, TValue>> expression, byte[] array, string Id)
{
TagBuilder tb = new TagBuilder("img");
tb.MergeAttribute("id", Id);
var base64 = Convert.ToBase64String(array);
var imgSrc = String.Format("data:image/gif;base64,{0}", base64);
tb.MergeAttribute("src", imgSrc);
return MvcHtmlString.Create(tb.ToString(TagRenderMode.SelfClosing));
}
ビューは次を受け取っています: ICollection オブジェクトなので、foreach ステートメントのビューで使用する必要があります。
@foreach (var item in Model)
@Html.GetBytes(itemP1 => item.Pic1, item.Graphics, "Idtag")
}