[c#] ASP.Net 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" />


답변

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

여기에 많은 “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" })