MVC So zeigen Sie ein Byte-Array-Bild vom Modell an

Ich habe ein Modell mit einer Byte-Array-Bilddatei, die ich auf der Seite anzeigen möchte.

Wie kann ich das tun, ohne zurück zur database zu gehen?

Alle Lösungen, die ich sehe, verwenden ein ActionResult, um zurück in die database zu gehen, um das Bild zu erhalten, aber ich habe bereits das Bild auf dem Modell …

So etwas mag funktionieren …

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

Wie in den Kommentaren unten erwähnt, verwenden Sie bitte das oben genannte mit dem Wissen, dass, obwohl dies Ihre Frage beantworten kann, es Ihr Problem möglicherweise nicht lösen kann . Abhängig von Ihrem Problem könnte dies die Lösung sein, aber ich würde den Zugriff auf die database nicht vollständig ausschließen.

Das hat für mich funktioniert

  

Ich empfehle etwas in dieser Richtung, auch wenn das Bild in Ihrem Modell lebt.

Ich weiß, dass du direkt aus der Sicht einen direkten Weg suchst, um darauf zuzugreifen, und viele andere haben das beantwortet und dir gesagt, was mit diesem Ansatz falsch ist, also ist dies nur ein weiterer Weg, das Bild für dich und mich asynchron zu laden denke, ist ein besserer Ansatz.

Beispielmodell:

 [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. } 

Beispielmethode im Controller:

 public async Task RenderImage(int id) { Item item = await db.Items.FindAsync(id); byte[] photoBack = item.InternalImage; return File(photoBack, "image/png"); } 

Aussicht

 @model YourNameSpace.Models.Item @{ ViewBag.Title = "Details"; } 

Details

Item


@Html.DisplayNameFor(model => model.Name)
@Html.DisplayFor(model => model.Name)

Eine Möglichkeit besteht darin, dies einer neuen c # -class oder HtmlExtensions-class hinzuzufügen

 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(""); } } 

dann können Sie das in jeder Hinsicht tun

 @Html.Image(Model.ImgBytes) 

Wenn Sie Ihre Bytes codieren können, könnten Sie versuchen, das Ergebnis als Bildquelle zu verwenden. In Ihrem Modell können Sie etwas hinzufügen wie:

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

Und Ihrer Meinung nach:

  

Wenn das Bild nicht so groß ist, und wenn es eine gute Chance gibt, werden Sie das Bild oft wiederverwenden, und wenn Sie nicht zu viele davon haben, und wenn die Bilder nicht geheim sind (was bedeutet, dass es nicht groß ist) Deal, wenn ein Benutzer das Bild einer anderen Person sehen könnte) …

Viele “If” s hier, also ist es eine gute Chance, das ist eine schlechte Idee:

Sie können die Cache für kurze Zeit im Cache speichern und ein Image-Tag auf eine Aktionsmethode richten, die wiederum aus dem Cache liest und Ihr Image ausspuckt. Dadurch kann der Browser das Bild entsprechend zwischenspeichern.

 // 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:  // 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"); } 

Dies hat den zusätzlichen Vorteil (oder ist es eine Krücke?), In älteren Browsern zu arbeiten, wo die Inline-Images nicht in IE7 funktionieren (oder IE8, wenn sie größer als 32kB sind).

Dies ist eine modifizierte Version von Manojs Antwort, die ich für ein Projekt verwende. Gerade aktualisiert, um eine class, HTML-Attribute zu nehmen und den TagBuilder zu verwenden.

  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)); } 

Welches kann dann wie folgt verwendet werden:

  @Html.Image(Model.Image, "img-cls", new { width="200", height="200" }) 

Sie müssen ein Byte [] in Ihrem DB haben.

Mein Byte [] befindet sich in meinem Person-Objekt:

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

Sie müssen Ihr Byte [] in einem String konvertieren. Also, ich habe in meinem Controller:

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

Als Nächstes ist mein Model in meiner .cshtml-Datei ein ViewModel. Das ist was ich habe in:

  public String Image { get; set; } 

Ich benutze es so in meiner .cshtml Datei:

  

“Daten: image / image Dateierweiterung ; base64, {0}, Ihr Bild String

Ich wünschte, es würde jemandem helfen!

Wenn Sie das Bild darstellen möchten, fügen Sie eine Methode als Hilfsklasse oder zum Modell selbst hinzu und ermöglichen Sie der Methode, das Byte-Array-Bild in ein Bildformat wie PNG oder JPG zu konvertieren und dann in Base64-String zu konvertieren. Sobald Sie das haben, binden Sie den base64-Wert für Ihre Ansicht im Format

“data: image / [Bild-Dateityp-Erweiterung] ; base64, [Ihre Base64-Zeichenfolge geht hier]

Das obige wird dem src Attribut des img Tags zugewiesen.

Das einzige Problem, das ich damit habe, ist die Base64-Zeichenfolge, die zu lang ist. Ich würde es daher nicht empfehlen, wenn mehrere Modelle in einer Ansicht angezeigt werden.

Ich habe eine Hilfsmethode erstellt, die unten im asnwer basiert, und ich bin ziemlich froh, dass dieser Helfer so vielen wie möglich helfen kann.

Mit einem Modell:

  public class Images { [Key] public int ImagesId { get; set; } [DisplayName("Image")] public Byte[] Pic1 { get; set; } } 

Der Helfer ist:

 public static IHtmlString GetBytes(this HtmlHelper helper, System.Linq.Expressions.Expression> 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)); } 

Die Ansicht empfängt ein: ICollection-Objekt, sodass Sie es in der Ansicht in einer foreach-statement verwenden müssen:

  @foreach (var item in Model) @Html.GetBytes(itemP1 => item.Pic1, item.Graphics, "Idtag") }