페이지에 표시하려는 바이트 배열 이미지 파일이있는 모델이 있습니다.
데이터베이스로 돌아 가지 않고 어떻게 할 수 있습니까?
내가 보는 모든 솔루션은를 사용 ActionResult
하여 데이터베이스로 돌아가 이미지를 검색하지만 이미 모델에 이미지가 있습니다.
페이지에 표시하려는 바이트 배열 이미지 파일이있는 모델이 있습니다.
데이터베이스로 돌아 가지 않고 어떻게 할 수 있습니까?
내가 보는 모든 솔루션은를 사용 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" })
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 / image file extension ; base64, {0}, your image String "
누군가를 도울 것입니다!
이미지를 표시하려면 메서드를 도우미 클래스로 추가하거나 모델 자체에 추가하고 메서드가 바이트 배열 이미지를 PNG 또는 JPG와 같은 이미지 형식으로 변환 한 다음 Base64 문자열로 변환하도록 허용합니다. 그런 다음 뷰의 base64 값을 형식으로 바인딩하십시오.
"data : image / [이미지 파일 유형 확장자] ; base64, [여기에 base64 문자열 입력] "
위는 img
태그의 src
속성에 할당됩니다 .
내가 가진 유일한 문제는 base64 문자열이 너무 길다는 것입니다. 따라서보기에 여러 모델이 표시되는 경우에는 권장하지 않습니다.
아래 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")
}