ฉันมีโมเดลที่มีไฟล์อิมเมจไบต์อาร์เรย์ที่ฉันต้องการแสดงบนเพจ
ฉันจะทำได้อย่างไรโดยไม่ต้องกลับไปที่ฐานข้อมูล
วิธีแก้ปัญหาทั้งหมดที่ฉันเห็นใช้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 (หรือ IE8 หากมีขนาดใหญ่กว่า 32kB)
นี่คือคำตอบของ 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" })
คุณต้องมีไบต์ [] ในฐานข้อมูลของคุณ
ไบต์ของฉัน [] อยู่ในวัตถุบุคคลของฉัน:
public class Person
{
public byte[] Image { get; set; }
}
คุณต้องแปลงไบต์ [] ของคุณในสตริง ดังนั้นฉันมีในคอนโทรลเลอร์ของฉัน:
String img = Convert.ToBase64String(person.Image);
ถัดไปในไฟล์. cshtml ของฉัน Model ของฉันคือ 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 ยาวเกินไป ดังนั้นฉันไม่แนะนำให้ใช้กับโมเดลหลาย ๆ แบบที่แสดงในมุมมอง
ฉันได้สร้างวิธีการช่วยเหลือตามคำแนะนำด้านล่างและฉันดีใจมากที่ตัวช่วยนี้สามารถช่วยได้มากที่สุด
ด้วยแบบจำลอง:
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")
}