This is a migrated thread and some comments may be shown as answers.
Render image (byte[]) on kendo templates from Model
9 Answers 621 Views
This is a migrated thread and some comments may be shown as answers.
figueiredorj
Top achievements
Rank 1
figueiredorj asked on 11 Dec 2012, 11:20 AM
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

9 Answers, 1 is accepted

Sort by
0
Vladimir Iliev
Telerik team
answered on 13 Dec 2012, 09:09 AM
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!
0
figueiredorj
Top achievements
Rank 1
answered on 13 Dec 2012, 10:03 AM
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
0
Vladimir Iliev
Telerik team
answered on 15 Dec 2012, 11:27 AM
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!
0
Raul
Top achievements
Rank 1
answered on 15 Dec 2016, 12:50 PM

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.

 

 

0
Stefan
Telerik team
answered on 19 Dec 2016, 01:00 PM
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.
0
Raul
Top achievements
Rank 1
answered on 19 Dec 2016, 03:58 PM

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.

0
Stefan
Telerik team
answered on 21 Dec 2016, 01:54 PM
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 (charts) and form elements.
0
Vladimir
Top achievements
Rank 1
answered on 27 Aug 2019, 09:43 PM
I downloaded zip file from the last post and found no single view file.
0
Nencho
Telerik team
answered on 29 Aug 2019, 11:47 AM

Hello Vladimir,

Below you can find our public repo with MVC examples, containing the one from the previous reply. Indeed, the views are missing in the attachments from this thread, but they are present in the example below:

https://github.com/telerik/ui-for-aspnet-mvc-examples/tree/master/grid/grid-render-byte-and-base64-images-and-show-preview-using-window

Hope this would help.

Regards,
Nencho
Progress Telerik

Get quickly onboarded and successful with your Telerik and/or Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
Asked by
figueiredorj
Top achievements
Rank 1
Answers by
Vladimir Iliev
Telerik team
figueiredorj
Top achievements
Rank 1
Raul
Top achievements
Rank 1
Stefan
Telerik team
Vladimir
Top achievements
Rank 1
Nencho
Telerik team
Share this question
or