Render image (byte[]) on kendo templates from Model

8 posts, 0 answers
  1. figueiredorj
    figueiredorj avatar
    68 posts
    Member since:
    Mar 2011

    Posted 11 Dec 2012 Link to this post

    Hi.

    I am trying to render image that is brought together on Model with full object.
    I know that most people use to render action (make a new request) only for image with Id, but that seems to me too much load just to display an image.

    Is there any way that an image can be rendered with model?

    My demo with northwind has this
    @using Kendo.Mvc.UI
    @model IEnumerable<MvcApplication_KendoTest.Data.Employee>
     
    <script type="text/x-kendo-tmpl" id="template">
        <div class="employee">

        <img src="${Image}"/>
     
            <h3>${Name} ${Lastname}</h3>
          
     
        </div>
    </script>
     
    <h2>@ViewBag.Title</h2>
     
    @(Html.Kendo().ListView<MvcApplication_KendoTest.Data.Employee>(Model)
        .Name("listView")
        .TagName("div")
        .ClientTemplateId("template")
        .DataSource(dataSource => {
            dataSource.Read(read => read.Action("Index", "Home"));
            dataSource.PageSize(12);
        })
        .Pageable()       
    )
    On my template I am tryig to render an image of employee. However this renders [object Object].
    Can some one help me?...

    Thanks in advance
  2. Vladimir Iliev
    Admin
    Vladimir Iliev avatar
    2190 posts

    Posted 13 Dec 2012 Link to this post

    Hi Ricardo,


    Please note that it's not possible to render directly byte array in html Image tag Src attribute. Possible solution is to convert the byte array to base64 string and render it in the template using DataURI scheme, however this approach has some limitations - IE7 is not supporting DataURI scheme and I would suggest to use render action(new request) for image by given Id.

    Rendering base64 image example:
    <script type="text/x-kendo-tmpl" id="template">
        <div class="employee">
     
        <img src="data:image/png;base64,${Image}"/>
      
            <h3>${Name} ${Lastname}</h3>
           
      
        </div>
    </script>


    Kind Regards,
    Vladimir Iliev
    the Telerik team
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
  3. figueiredorj
    figueiredorj avatar
    68 posts
    Member since:
    Mar 2011

    Posted 13 Dec 2012 Link to this post

    Hi Vladimir.

    Thanks for your response.
    If I understood you well you are saying for me to convert byte[] to string base64.

    So I have set this like:

    public class Employee
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string Lastname { get; set; }
        public byte[] Image { get; set; }
     
        public string Image64{get { return Image != null ? Convert.ToBase64String(Image) : null ; }}
    }
    And on view I define template as so:

    <script type="text/x-kendo-tmpl" id="template">
        <div class="employee">
            <img src="data:image/png;base64,${Image64}"/>
     
        <h3>${Name} ${Lastname}</h3>  
     
        </div>
    </script>
    However this haven't done the trick.
    What I am missing?

    And how would it be to setup render action on template?
    Would I have to setup a trigger?
    Note that this would be  inefficient if for each image it would have to make a request/trip to server so  my action would have to return an array. Could you develop the idea a little more?

    Perhaps this could be something that kendo could improve in future (rendering images on templates from byte[]). You must agree with me that it isn't suit for major applications aren't suited to have images on server as files. And for Grids and ListView there is for times need to display images.

    Thanks again
  4. Vladimir Iliev
    Admin
    Vladimir Iliev avatar
    2190 posts

    Posted 15 Dec 2012 Link to this post

    Hi Ricardo,

     
    Please note that rendering images from byte array on the client side is not directly related to KendoUI but to general knowledge - more information on the matter can be found on various resources over the internet (you can check this post for more information). Also I would suggest to store only the file paths in the DataBase instead of byte array or base64 strings.

    For convenience I created example of rendering images in the Grid from both the base64 string and byte array and attached it to the current thread. 

    Kind Regards,
    Vladimir Iliev
    the Telerik team
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
  5. Raul
    Raul avatar
    20 posts
    Member since:
    Apr 2016

    Posted 15 Dec 2016 Link to this post

    Hi Vladimir,

    I am not able to see the pictures in my kendo grid. I have followed your instructions but I don't see anything.

    This is my View code:

        @(Html.Kendo().Grid<AttachedFileModel>()
            .Name("PicturesGrid")
            .ToolBar(toolbar =>
            {
                toolbar.Save();
            })
            .ToolBar(t => t.Template(
                @<text>
                    @(Html.Kendo().Upload()
                        .Name("files")
                        .Messages(m => m.Select("Attach Files"))
                        .Async(a => a.Save("SaveFile", "AuditForm"))
                        .HtmlAttributes(new { accept = "image/*" })
                        .Events(e => e
                            .Success("onUploadSuccess")
                            .Upload("onUpload"))
                        .ShowFileList(false) // Hide the file list as we're displaying uploaded files in the Grid
                    )
                </text>
                ))
            .Columns(columns =>
            {
                columns.Bound(f => f.Id).Visible(false);
                columns.Bound(f => f.AuditId).Visible(false);
                columns.Bound(f => f.Image64).ClientTemplate(@"<div class='supplier-picture' <img src='" + "data:image/gif;base64,#=Image64# alt=" + "image" + "'></div>").Width(100).Title("Image");
                columns.Bound(f => f.Image64)
                    .ClientTemplate("<img src='data:image/png;base64,#=Image64#' />")
                    .Title("Base64 Images");
                columns.Bound(f => f.FileContent).ClientTemplate(@"<div class='supplier-picture' <img src='" + "#=FileContent# alt=" + "image" + "'></div>").Width(100).Title("Image2");
                columns.Bound(f => f.FileName).Width(200).ClientTemplate("<a href='Download?id=#= Id #&filename=#= FileName #'>#= FileName #</a>").Title("File name");
                columns.Bound(f => f.FileDescription).Width(400).Filterable(false).Title("File Description");
                // Calculate the file size in KB, round it up and display it in a client template
                //columns.Bound(f => f.DataLength).ClientTemplate("#= Math.ceil(DataLength / 1024) #").Title("Size (KB)").Width(100);
                columns.Command(command =>
                {
                    command.Edit().Text("Update");
                    command.Destroy();
                }).Width(160);
            })
            .DataSource(dataSource => dataSource
                .Ajax()
                .PageSize(5)
                .Model(m =>
                {
                    m.Id(f => f.Id);
                    m.Field(f => f.AuditId).Editable(false);
                    m.Field(f => f.FileDescription).Editable(true);
                    m.Field(f => f.FileName).Editable(false);
                    m.Field(f => f.FileContent).Editable(false);
                })
                //.Read(read => read.Action("FilesRead", "AuditForm", new { id = Model.AuditPlan.AuditId }))
                .Read(read => read.Action("FilesRead", "AuditForm").Data("additionalInfo"))
                .Update(update => update.Action("UpdateFileDescription", "AuditForm"))
                .Destroy(destroy => destroy.Action("FilesDestroy", "AuditForm"))
            )
            .Events(events =>
            {
                //events.DataBound("dataBound");
                events.Remove("onRemoveFileGrid");
            })
            .Sortable(sortable =>
            {
                sortable.AllowUnsort(false);
            })
            .Resizable(resize => resize.Columns(true))
            .Scrollable(scr => scr.Height(300))
            .Pageable(pageable => pageable
                .Refresh(true)
                .PageSizes(true)
                .PageSizes(new int[] { 5, 10, 20, 30 })
                .ButtonCount(5))
            .Editable(editable => editable.Mode(GridEditMode.InCell))
            .Editable(editable => editable.Enabled(true))
        )

     

    This is my Model :

        public class AttachedFileModel
        {
            public int Id { get; set; }
            public string FileName { get; set; }
            public byte[] FileContent { get; set; }
            public string FileDescription { get; set; }
            public int AuditId { get; set; }
            public Nullable<int> SectionId { get; set; }
            public int? DataLength { get; set; }
            public string Image64 { get { return FileContent != null ? Convert.ToBase64String(FileContent) : null; } }

        }

     

    This is part of my controller : (Read)

            public ActionResult _SupplierPicsTab()
            {
                return View();
            }

            public ActionResult FilesRead([DataSourceRequest] DataSourceRequest request, int id)
            {
                //var attachmentfile = auditFormService.FilesRead(id).ToList();
                //return Json(attachmentfile.ToDataSourceResult(request, ModelState));

                var attachmentfile = Json(auditFormService.FilesRead(id).ToList().ToDataSourceResult(request, ModelState), JsonRequestBehavior.AllowGet);
                attachmentfile.MaxJsonLength = int.MaxValue;

                return attachmentfile;


            }

     

    Files are saved in a database as :

    [FileContent] [varbinary](max) NULL

     

    Please, I need your help.

    Thanks in advanced.

    Raul.

     

     

  6. Stefan
    Admin
    Stefan avatar
    728 posts

    Posted 19 Dec 2016 Link to this post

    Hello Raul,

    After inspecting the example I noticed that Image64 is not in the model, but it is used in the ClientTemplate.

    Also, please check our example for using regular images inside a ClientTemplate:

    http://demos.telerik.com/aspnet-mvc/grid/index

    Additionally, as rendering images from Base64 string is not directly related to Kendo UI Grid, please check if the image will be correctly rendered on the page without using it in the Grid, to confirm if the issue is indeed with the Grid, so we can investigate further.

    Regards,
    Stefan
    Telerik by Progress
    Try our brand new, jQuery-free Angular 2 components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
  7. Raul
    Raul avatar
    20 posts
    Member since:
    Apr 2016

    Posted 19 Dec 2016 in reply to Stefan Link to this post

    Hello Stefan,

    Thank you for your reply ...

    As you can see in attached file the model contains 'Image64' field. (Probably you didn't see it).

    We are saving our files into the database, so we need to take the pictures directly from there instead of save them in File system in one Server. 

    This is my definition of the columns in the grid :

            .Columns(columns =>
            {
                columns.Bound(f => f.Id).Visible(false);
                columns.Bound(f => f.AuditId).Visible(false);
                columns.Bound(f => f.Image64).ClientTemplate(@"<div class='supplier-picture' <img src='" + "data:image/gif;base64,#=Image64# alt=" + "image" + "'></div>").Width(100).Title("Image");
                columns.Bound(f => f.FileContent).ClientTemplate("<img src='" + Url.Content("~/Images/") + "#=FileName#' alt='#=FileName #' Title='#=FileName #' height='62' width='62'/>").Title("Image");
                columns.Bound(f => f.FileName).Width(200).ClientTemplate("<a href='Download?id=#= Id #&filename=#= FileName #'>#= FileName #</a>").Title("File name");
                columns.Bound(f => f.FileDescription).Width(400).Filterable(false).Title("File Description");
                // Calculate the file size in KB, round it up and display it in a client template
                //columns.Bound(f => f.DataLength).ClientTemplate("#= Math.ceil(DataLength / 1024) #").Title("Size (KB)").Width(100);
                columns.Command(command =>
                {
                    //command.Edit().Text("Update");
                    command.Custom("UpdateAttachedFile").Text("Update").Click("UpdateAttachedFile");
                    command.Custom("Delete").Click("OnDeleteAttachedFile");
                }).Width(160);
            })

     

    I have attached the image with the final result too.

    As you can see the column with the files in the server is being renderized, but the image obtained from the database not.

    Please, can you help me.

    Best Regards.

    Raúl.

  8. Stefan
    Admin
    Stefan avatar
    728 posts

    Posted 21 Dec 2016 Link to this post

    Hello Raul,

    I tested our example and it is still working as expected with the latest version of Kendo UI.

    My remark for the Image64 was that it was not included in the DataSource model.

    I can suggest checking if the images will be rendered on a page as simple image files without the Grid. If the images as correctly rendered from the database on the page but not in the Grid, please provide a runnable example so we can investigate what may be causing the issue.

    I attached the example modified to work with the latest version of Kendo UI.

    Regards,
    Stefan
    Telerik by Progress
    Try our brand new, jQuery-free Angular 2 components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
Back to Top