development

MVC 모델에서 바이트 배열 이미지를 표시하는 방법

big-blog 2020. 8. 15. 09:50
반응형

MVC 모델에서 바이트 배열 이미지를 표시하는 방법


페이지에 표시하려는 바이트 배열 이미지 파일이있는 모델이 있습니다.

데이터베이스로 돌아 가지 않고 어떻게 할 수 있습니까?

내가 보는 모든 솔루션은 ActionResult를 사용하여 데이터베이스로 돌아가 이미지를 검색하지만 이미 모델에 이미지가 있습니다.


이런 식으로 작동 할 수 있습니다 ...

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

<img src="@imgSrc" />

아래 의견에서 언급했듯이 위의 내용은 귀하의 질문에 답할 수 있지만 문제가 해결되지 않을 수 있다는 사실을 알고 사용하십시오 . 문제에 따라 이것이 해결책이 될 수 있지만 데이터베이스에 두 번 액세스하는 것을 완전히 배제하지는 않습니다.


이것은 나를 위해 일했습니다.

<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>

한 가지 방법은이를 새 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)

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" />

이미지가 그다지 크지 않고 좋은 기회가 있다면 이미지를 자주 재사용하고 이미지가 너무 많지 않고 이미지가 비밀이 아닌 경우 (크지 않다는 의미) 한 사용자가 잠재적으로 다른 사람의 이미지를 볼 수있는 경우 거래) ...

Lots of "if"s here, so there's a good chance this is a bad idea:

You can store the image bytes in Cache for a short time, and make an image tag pointed toward an action method, which in turn reads from the cache and spits out your image. This will allow the browser to cache the image appropriately.

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

This has the added benefit (or is it a crutch?) of working in older browsers, where the inline images don't work in IE7 (or IE8 if larger than 32kB).


This is an modified version of Manoj's answer that I use on a project. Just updated to take a class, html attributes and use the 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));
    }

Which can be used then as follows:

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

You need to have a byte[] in your DB.

My byte[] is in my Person object:

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


You need to convert your byte[] in a String. So, I have in my controller :

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


Next, in my .cshtml file, my Model is a ViewModel. This is what I have in :

 public String Image { get; set; }


I use it like this in my .cshtml file:

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

"data:image/image file extension;base64,{0}, your image String"

I wish it will help someone !


If you want to present the image, add a method as a helper class or to the model itself and allow the method to convert the byte array image to a image format like PNG or JPG then convert to Base64 string. Once you have that, bind the base64 value on your view in the format

"data:image/[image file type extension];base64,[your base64 string goes here]"

The above is assigned to the img tag's src attribute.

The only issue I have with this is the base64 string being too long. So, I would not recommend it for multiple models being shown in a view.


I've created a helper method based in the asnwer below and I'm pretty glad that this helper can help as many as possible.

With a model:

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

The helper is:

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

The view is receiving a: ICollection object so you need to used it in the view in a foreach statement:

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

참고URL : https://stackoverflow.com/questions/17952514/mvc-how-to-display-a-byte-array-image-from-model

반응형