web-dev-qa-db-ja.com

MVCモデルからバイト配列画像を表示する方法

ページに表示したいバイト配列の画像ファイルを持つモデルがあります。

データベースに戻らずにこれを行うにはどうすればよいですか?

私が見るすべてのソリューションはActionResultを使用してデータベースに戻って画像を取得しますが、すでにモデルに画像があります...

94
DK ALT

このような何かが動作する可能性があります...

@{
    var base64 = Convert.ToBase64String(Model.ByteArray);
    var imgSrc = String.Format("data:image/gif;base64,{0}", base64);
}

<img src="@imgSrc" />

以下のコメントで述べたように、これはあなたの質問に答えることはできますが、問題を解決できないかもしれませんという知識を持って上記を使用してください。あなたの問題にもよりますが、これは解決策かもしれませんが、データベースに2回アクセスすることを完全に排除するつもりはありません。

183
dav_i

これは私のために働いた

<img src="data:image;base64,@System.Convert.ToBase64String(Model.CategoryPicture.Content)" width="80" height="80"/>     
34
NoloMokgosi

画像がモデル内にある場合でも、これらの線に沿って何かをお勧めします。

私はあなたがビューから直接アクセスする直接的な方法を求めていることを理解しており、他の多くの人がそれに答えて、そのアプローチの何が悪いのかをあなたに伝えたので、これはあなたにとって非同期のイメージで、私はより良いアプローチだと思います。

サンプルモデル:

[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>
23
Louie Bacaj

1つの方法は、これを新しいc#クラスまたはHtmlExtensionsクラスに追加することです

public static class HtmlExtensions
{
    public static MvcHtmlString Image(this HtmlHelper html, byte[] image)
    {
        var img = String.Format("data:image/jpg;base64,{0}", Convert.ToBase64String(image));
        return new MvcHtmlString("<img src='" + img + "' />");
    }
}

その後、任意のビューでこれを行うことができます

@Html.Image(Model.ImgBytes)
10
Moji

バイトをbase-64でエンコードできる場合は、結果を画像ソースとして使用してみてください。モデルには次のようなものを追加できます。

public string ImageSource
{
    get
    {
        string mimeType = /* Get mime type somehow (e.g. "image/png") */;
        string base64 = Convert.ToBase64String(yourImageBytes);
        return string.Format("data:{0};base64,{1}", mimeType, base64);
    }
}

そしてあなたの見解では:

<img ... src="@Model.ImageSource" />
10
Cᴏʀʏ

画像がそれほど大きくない場合、そして可能性が高い場合、画像を頻繁に再利用し、あまり多くない場合、および画像が秘密でない場合(画像が大きくないことを意味します)あるユーザーが別の人の画像を見る可能性がある場合に対処する...).

ここには「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)でインラインイメージが機能しない古いブラウザーで作業するという追加の利点(または松葉杖ですか?)があります。

5
Joe Enos

これは、プロジェクトで使用する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" })
2
AlexH

DBにbyte []が必要です。

byte []はPersonオブジェクトにあります:

public class Person
{
    public byte[] Image { get; set; }
}


文字列のbyte []を変換する必要があります。だから、私は自分のコントローラーに:

String img = Convert.ToBase64String(person.Image);


次に、.cshtmlファイルでは、モデルがViewModelです。これは私が持っているものです:

 public String Image { get; set; }


。cshtmlファイルで次のように使用します。

<img src="@String.Format("data:image/jpg;base64,{0}", Model.Image)" />

"data:image/画像ファイル拡張子; base64、{0}、画像文字列"

私はそれが誰かを助けることを望みます!

2
Thorpe

以下のasnwerに基づいてヘルパーメソッドを作成しました。このヘルパーが可能な限り多くのことを支援できることを非常に嬉しく思います。

モデルの場合:

 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")
}
0
Jose Ortega

画像を表示する場合は、ヘルパークラスまたはモデル自体にメソッドを追加し、メソッドがバイト配列画像をPNGやJPGなどの画像形式に変換してからBase64文字列に変換できるようにします。それができたら、次の形式でビューのbase64値をバインドします

"data:image/[画像ファイルの種類の拡張子]; base64、[base64文字列がここに来る]"

上記はimgタグのsrc属性に割り当てられます。

これに関する唯一の問題は、base64文字列が長すぎることです。そのため、ビューに表示される複数のモデルにはお勧めしません。

0
mitch