ASP.Net MVC: मॉडल से बाइट सरणी छवि कैसे प्रदर्शित करें


115

मेरे पास एक बाइट सरणी छवि फ़ाइल वाला एक मॉडल है जिसे मैं पृष्ठ पर दिखाना चाहता हूं।

डेटाबेस में वापस जाए बिना मैं ऐसा कैसे कर सकता हूं?

सभी समाधान जो मुझे दिखाई ActionResultदेते हैं वे छवि को पुनः प्राप्त करने के लिए डेटाबेस में वापस जाने के लिए उपयोग करते हैं, लेकिन मेरे पास पहले से ही मॉडल पर छवि है ...


11
कृपया, "ASP.NET MVC" को "MVC" के रूप में देखें। एक ढांचा है, जबकि अन्य भाषा-स्वतंत्र डिजाइन पैटर्न है। यह IE की तरह है - "इंटरनेट"
tereško

MVC मॉडल से बाइट सरणी छवि को प्रदर्शित करने के लिए कैसे?
छठ

जवाबों:


214

कुछ इस तरह से हो सकता है काम ...

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

<img src="@imgSrc" />

जैसा कि नीचे टिप्पणी में उल्लेख किया गया है, कृपया उपरोक्त सशस्त्र का उपयोग इस ज्ञान के साथ करें कि यद्यपि यह आपके प्रश्न का उत्तर दे सकता है लेकिन यह आपकी समस्या का समाधान नहीं कर सकता है । आपकी समस्या के आधार पर यह समाधान हो सकता है लेकिन मैं दो बार डेटाबेस तक पहुंचने से पूरी तरह से इनकार नहीं करूंगा।


6
यह ध्यान दिया जाना चाहिए कि यह HTML में छवि को एम्बेड करेगा और कई मानक छवि कैशिंग तकनीकों को दरकिनार करेगा।
क्विंटन रॉबिन्सन

@QuintinRobinson यद्यपि अनुरोधों की संख्या को कम करता है:)
dav_i

8
@dav_i प्रारंभिक अनुरोधों की संख्या कम करें । वेब प्रदर्शन का अनुकूलन करते समय सर्वरों, मध्यस्थ सामग्री प्लेटफार्मों और जानकारी का अनुरोध करने और संसाधित करने वाले क्लाइंट्स के मैकेनिक्स को समझना अविश्वसनीय रूप से महत्वपूर्ण है। मैं एक टिप्पणी में असाधारण विस्तार में नहीं जाना चाहता हूं लेकिन मैं इस तरह की तकनीक का उपयोग करने के निहितार्थ को समझने की आवश्यकता पर जोर देना चाहता हूं।
क्विंटन रॉबिन्सन

1
प्रश्न के लिए उत्तर सही हो सकता है लेकिन मुझे लगता है कि जिस समस्या को हम हल करने की कोशिश कर रहे हैं, उसमें दोष है। यदि हाथ में समस्या डेटा प्राप्त करने के लिए डेटाबेस में दो कॉल को रोक रही है और फिर छवि प्राप्त करने के लिए एक सेकंड मुझे लगता है कि एक बेहतर समाधान एक हैंडलर का उपयोग करना होगा जो सर्वर पर समग्र भार को कम करने के लिए कैशिंग को लागू कर सकता है। जब आप यह जानने की कोशिश कर रहे हैं कि आपका एप्लिकेशन क्यों चोक रहा है क्योंकि आप बेस 64 एन्कोडिंग का उपयोग करके पेज रिस्पांस स्ट्रीम में एक बड़ी फाइल को डंप करने की कोशिश कर रहे हैं, तो आप चाहेंगे कि आपने बड़ी तस्वीर के बारे में अधिक सोचा था।
निक बोर्क

2
महान, मैंने इसे फिर से उपयोग करने के लिए अपने मॉडल पर एक विधि जोड़ी: सार्वजनिक स्ट्रिंग GetBase64 () {var base64 = Convert.ToBase64String (ContentImage); वापसी String.Format ("डेटा: छवि / gif; base64, {0}", base64); }
रोड्रिगो लोंगो

40

इसने मेरे लिए काम किया

<img src="data:image;base64,@System.Convert.ToBase64String(Model.CategoryPicture.Content)" width="80" height="80"/>     

1
इसने मेरे लिए भी काम किया, कृपया यह कहें कि मॉडल से एक बाइट सरणी छवि कैसे प्रदर्शित करें जब इसकी नल?
छठ

हाय छठ, मैं आपको सुझाव दूंगा कि दृश्य में पास होने से पहले नियंत्रक में मॉडल को मान्य करें। यदि मॉडल अशक्त है, तो एक डिफ़ॉल्ट चित्र पास करें
NoloMokgosi

26

मैं इन पंक्तियों के साथ कुछ सुझाता हूं, भले ही छवि आपके मॉडल के अंदर रहती हो।

मुझे लगता है कि आप इसे देखने के लिए सही तरीके से उपयोग करने के लिए एक सीधा रास्ता पूछ रहे हैं और कई अन्य लोगों ने जवाब दिया है और आपको बताया है कि उस दृष्टिकोण के साथ क्या गलत है इसलिए यह सिर्फ एक और तरीका है जो आपके और I के लिए async फैशन में छवि को लोड करेगा सोचना एक बेहतर तरीका है।

नमूना मॉडल:

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

2
"रिटर्न फाइल (...)" क्या है? एक स्थिर वर्ग फ़ाइल नहीं है?
बेन सीवार्ड्स

3
यह एक FileContentResult ऑब्जेक्ट ( msdn.microsoft.com/en-us/library/… ) होना चाहिए
Louie Bacaj

13

एक तरीका यह है कि इसे नए 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)

मुझे वास्तव में यह सबसे अच्छा लगता है - यह मॉडल में साफ करता है और .cshtml फ़ाइल में भी। महान!!
केन

10

यदि आप अपने बाइट्स को आधार बना सकते हैं, तो आप परिणाम का उपयोग अपने छवि स्रोत के रूप में कर सकते हैं। अपने मॉडल में आप कुछ ऐसा जोड़ सकते हैं:

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

5

यदि छवि इतनी बड़ी नहीं है, और यदि कोई अच्छा मौका है तो आप अक्सर छवि का फिर से उपयोग करेंगे, और यदि आपके पास उनमें से बहुत सारे नहीं हैं, और यदि चित्र गुप्त नहीं हैं (तो इसका अर्थ है कि यह कोई बड़ा नहीं है सौदा करें यदि एक उपयोगकर्ता संभावित रूप से किसी अन्य व्यक्ति की छवि देख सकता है ...)

"अगर" यहाँ बहुत है, तो एक अच्छा मौका है यह एक बुरा विचार है:

आप 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 से बड़ी) में काम नहीं करती हैं।


3

यह मनोज के उत्तर का एक संशोधित संस्करण है जिसका उपयोग मैं एक परियोजना पर करता हूं। बस एक क्लास लेने के लिए अपडेट किया गया, 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" })

3

आपको अपने DB में एक बाइट [] की आवश्यकता है।

मेरी बाइट [] मेरी व्यक्तिगत वस्तु में है:

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


आपको अपनी बाइट [] को एक स्ट्रिंग में परिवर्तित करने की आवश्यकता है। इसलिए, मेरे पास मेरे नियंत्रक हैं:

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


इसके बाद, .cshtml फ़ाइल में, मेरा मॉडल एक ViewModel है। यह मेरे पास है:

 public String Image { get; set; }


मैं इसे अपने .cshml फ़ाइल में इस तरह उपयोग करता हूं:

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

"डेटा: छवि / छवि फ़ाइल एक्सटेंशन ; आधार 64, {0}, आपकी छवि स्ट्रिंग "

काश यह किसी की मदद करेगा!


1

यदि आप छवि प्रस्तुत करना चाहते हैं, तो एक विधि को सहायक वर्ग के रूप में या स्वयं मॉडल में जोड़ें और बाइट सरणी छवि को PNG या JPG जैसे छवि प्रारूप में बदलने की अनुमति दें और फिर Base64 स्ट्रिंग में कनवर्ट करें। एक बार जब आप ऐसा कर लेते हैं, तो प्रारूप में अपने विचार पर आधार 64 मान को बांधें

"डेटा: इमेज / [इमेज फाइल टाइप एक्सटेंशन] ; आधार 64, [आपका बेस 64 स्ट्रिंग यहां जाता है] "

ऊपर imgटैग की srcविशेषता को सौंपा गया है ।

एकमात्र मुद्दा जो मेरे पास है, वह आधार 64 स्ट्रिंग बहुत लंबा है। इसलिए, मैं इसे एक दृश्य में दिखाए जाने वाले कई मॉडलों के लिए अनुशंसित नहीं करूंगा।


आप एक समस्या लाते हैं, और उपयोग की स्थिति की स्थिति की अनुशंसा करते हैं, लेकिन आपके उपयोग के मामले के परिदृश्य का कोई समाधान नहीं। इसने आपके उत्तर को बहुत अच्छा / उपयोगी और अधिक जानकारीपूर्ण बना दिया होगा।
केन

0

मैंने नीचे दिए गए 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 (var item in Model)
  @Html.GetBytes(itemP1 => item.Pic1, item.Graphics, "Idtag")
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.