Display an Image from a WebAPI call - c#

I have generated an image in my .Net backend service, and am sitting with a System.Drawing.Image object. I made a call to my WebAPI method, rendered the image, and would like to return the image to the front end, and display it.
Is there a way I can do something like:
self.Image = ko.observable();
And then load the image from my WebApi call, into self.Image (Not sure what the return type would be).
And then ?

It's actually pretty easy. You can use the attr binding to bind any html attribute. Here's a sample of using a button to do whatever you want (ajax included) to load the image. Side note, I'm not really sure what your image is coming back as, but you certainly can use data urls to bind as the src.
function viewModel() {
var self = this;
self.Image = ko.observable();
self.LoadImage = function() {
// Ajax stuff
self.Image("http://lorempizza.com/200/200");
}
}
ko.applyBindings(new viewModel())
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<img data-bind="attr: {src: Image} ">
<button data-bind="click: LoadImage">Load Image </button>

I worked it out:
[Route("Preview"), HttpPost]
public string Preview(PlateTemplateExtendedDto data)
{
var img = new PlateService().CreateTemplate(true);
using (var ms = new MemoryStream())
{
img.Save(ms, ImageFormat.Jpeg);
var base64 = "data:image/jpeg;base64," + Convert.ToBase64String(ms.ToArray());
return base64;
}
}
And then on the view, I just use that text as the source.
<img data-bind="attr:{src: image}" class="img-responsive" style="margin: 0 auto;" />

Related

Trying to call and bind image in img src tag from server in mvc

Hi i'm trying to bind image in img tag in mvc .this tag is used in asp.net like this in the same way i want to bind image in MVC/
eg
ASP.net
<img alt="User Image" width="80px" height="80px" class="img img-thumbnail" src='<%="http://196.0.2.201/p001.ashx?pf=YY&cid="+Session[CommonConstants.SESSION_USER_ID] %>'/>
in mvc
I want to pass #ViewBag.session as parameter instead of Session[CommonConstants.SESSION_USER_ID] how to achieve it in Mvc any idea would be appreciated.
If you're using MVC why not base64 the image on the server while the page is being constructed and embed that in the image src for example with Razor:
<img src="data:image/jpeg;base64, #Model.Base64Image">
This way any logic used for generating the image is part of the same controller logic that is building your page.
Step by step:
your razor page will have a #model ViewModel Directive at the top and an image element somewhere that you are populating as above, the jpeg part can be any image type must must match the type that is being encoded.
your view model should have a string property in this case called Base64Image.
your controller should have a part that gets and converts the image e.g.
public IActionResult Index()
{
var model = new ViewModel();
// important thing here is to convert the image into a byte array:
var imageBytes = System.IO.File.ReadAllBytes(#"image.jpeg");
// Convert byte array to Base64 String
model.Base64Image = Convert.ToBase64String(imageBytes);
// return View model with base64 encoded image to page
return View(model);
}
the rendered page at the client side will have an image element something like this.
<img src="data:image/jpeg;base64, TWFuIGlzIGRpc3RpbmdR== ">
the base64 encoding will be hundreds of characters long.
Doing it this way the client doesn't need to make a second call to get the image its already in the page. What you're trying to do is define an endpoint that the client will call on to get the image.
Declare a new model
public class ModelImg
{
public int MyProperty1 { get; set; }
public bool MyProperty2 { get; set; }
public string Img { get; set; }
}
use your object in controller :
ModelImg model = new ModelImg(){Img = #"MyImgAsString",MyProperty1 = 1,MyProperty2 = true};
Assign your object or your img directly to a ViewData in your controller view:
ViewData["Img"] = model.Img;
In your View assign your src :
<img alt="User Image" width="80px" height="80px" class="img img-thumbnail" src='ViewData["Img"]'/>

What is the diff between normal file upload and create thumbnails of an images using mvc?

Hi i am totally confused with file uploading. First of all any one explain me what is the difference between normal file uplaod and create thumbnail for image and save that path in db.
I checked the path of both normal and thumbnail. Moreover same only but i donno what is the differene between these two types of uplaod?.Can any one explain me these difference?
I tried both types. I paste that code here and any one tell me the difference between two types.
1) Normal Uplaod using AJAX
View
#{
ViewBag.Title = "FileUpload";
}
<head>
<title></title>
</head>
<body>
<input type="file" id="FileUpload1" />
<input type="button" id="btnUpload" value="Upload Files" />
</body>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"> </script>
<script>
$(document).ready(function(){
$('#btnUpload').click(function () {
// Checking whether FormData is available in browser
if (window.FormData !== undefined) {
var fileUpload = $("#FileUpload1").get(0);
var files = fileUpload.files;
// Create FormData object
var fileData = new FormData();
// Looping over all files and add it to FormData object
for (var i = 0; i < files.length; i++) {
fileData.append(files[i].name, files[i]);
}
// Adding one more key to FormData object
fileData.append('username', 'Manas');
$.ajax({
url: '/ImageUplaod/UploadFiles',
type: "POST",
contentType: false, // Not to set any content header
processData: false, // Not to process data
data: fileData,
success: function (result) {
alert(result);
},
error: function (err) {
alert(err.statusText);
}
});
} else {
alert("FormData is not supported.");
}
});
});
</script>
Controller
public ActionResult FileUpload()
{
return View();
}
[HttpPost]
public ActionResult UploadFiles()
{
// Checking no of files injected in Request object
if (Request.Files.Count > 0)
{
try
{
// Get all files from Request object
HttpFileCollectionBase files = Request.Files;
for (int i = 0; i < files.Count; i++)
{
//string path = AppDomain.CurrentDomain.BaseDirectory + "Uploads/";
//string filename = Path.GetFileName(Request.Files[i].FileName);
HttpPostedFileBase file = files[i];
string fname;
// Checking for Internet Explorer
if (Request.Browser.Browser.ToUpper() == "IE" || Request.Browser.Browser.ToUpper() == "INTERNETEXPLORER")
{
string[] testfiles = file.FileName.Split(new char[] { '\\' });
fname = testfiles[testfiles.Length - 1];
}
else
{
fname = file.FileName;
}
// Get the complete folder path and store the file inside it.
fname = Path.Combine(Server.MapPath("~/Uploads/"), fname);
file.SaveAs(fname);
var imageupload = new imageupload();
imageupload.ImageUplaod = fname;
db.imageuploads.Add(imageupload);
db.SaveChanges();
}
// Returns message that successfully uploaded
return Json("File Uploaded Successfully!");
}
catch (Exception ex)
{
return Json("Error occurred. Error details: " + ex.Message);
}
}
else
{
return Json("No files selected.");
}
}
2) Craete Thumbnails for image using MVC and save that path in db
Model
public class ImageUploadModels
{
[Key]
public int ImgageID
{
get;
set;
}
[Required]
public string ImagePath
{
get;
set;
}
}
Controller
public ActionResult Index()
{
return View();
}
[HttpPost]
public ActionResult ImageUploadThumnail(ImageUploadModels image, HttpPostedFileBase file)
{
try {
if (file != null)
{
var fileName = Path.GetFileName(file.FileName);
var thumbName = fileName.Split('.').ElementAt(0) + "_thumb." + fileName.Split('.').ElementAt(1);
fileName = Path.Combine(Server.MapPath("/Images"), fileName);
thumbName = Path.Combine(Server.MapPath("/Images"), thumbName);
image.ImagePath = fileName; //to store into database, if we use DbContext
file.SaveAs(fileName);
Image img = Image.FromFile(fileName);
int imgHeight = 100;
int imgWidth = 100;
if (img.Width < img.Height)
{
//portrait image
imgHeight = 100;
var imgRatio = (float) imgHeight / (float) img.Height;
imgWidth = Convert.ToInt32(img.Height * imgRatio);
}
else if(img.Height < img.Width)
{
//landscape image
imgWidth = 100;
var imgRatio = (float) imgWidth / (float) img.Width;
imgHeight = Convert.ToInt32(img.Height * imgRatio);
}
Image thumb = img.GetThumbnailImage(imgWidth, imgHeight, () => false, IntPtr.Zero);
thumb.Save(thumbName);
var imageupload = new imageupload();
imageupload.ImageUplaod = thumbName;
db.imageuploads.Add(imageupload);
db.SaveChanges();
}
return View();
} catch (Exception ex)
{
ViewBag.Message = ex.Message.ToString();
return View();
}
}
View
#model ImageUpload.Models.ImageUploadModels
#{
ViewBag.Title = "Index";
}
#using (Html.BeginForm("ImageUploadThumnail", "ImageUplaod", null, FormMethod.Post, new
{
enctype = "multipart/form-data"
})) {
#Html.AntiForgeryToken()
#Html.ValidationSummary(true);
<fieldset> <legend> Image </legend>
<div class = "editor-label" >
#Html.LabelFor(model => model.ImagePath)
</div>
<div class = "editor-field">
<input id = "ImagePath" title = "Upload an image" type = "file" name = "file"/>
</div>
<p> <input type = "submit" value = "Upload"/>
</p>
</fieldset>
}
Now i posted two typesof upload what i tried . i want to know the difference between these two types and i want to know which is better to upload image in server after deploying the project. And also any one tell me how to create thumbnails for image using ajax . Here in above mention method i didn't use ajax for thumbnails . But i need to uplaod and save the path of the thumnails image using ajax. I tried my level best to explain my issue.Any one understand my issue and give me solution for this problem
Advance Thanks..
First of all any one explain me what is the difference between normal file uplaod and create thumbnail for image and save that path in db.
What is a thumbnail image?
It is just an image that looks like another image but with a smaller file size.
Advantages of using thumbnails on web
This can play a major role in web applications. When you visit a web page, like this one, if there are images on the page they need to be brought to your computer so your browser can show them to you. In other words, they need to be downloaded to your computer. Web sites developed with that in mind, will just include a low quality, small size image of the actual image and send that when you view the page. Then when you click on the image, for example, if you want to look at the image more closely, then the browser will make another request to the server and get the high quality image.
This technique makes the initial loading (downloading to be exact) fast so the user is not setting there waiting for all the big images if all they want to do is read something.
I am not sure if you are using uploading incorrectly but uploading is the opposite of downloading. When you visit a page, you are essentially downloading the page (unless you have already visited the page and the browser has cached it.) Therefore, uploading is you sending something to the server and I am not sure how sending something to the server will benefit from thumbnails.
I think what you may be speaking of is having a thumbnail image and the path to the high quality image of the thumbnail is stored in the db with thumbnail data. You send the thumbnail when someone requests it, then if they want the higher quality image, you get the path from the database and serve the high quality image.
This technique is highly in use by commerce sites. For example, when you are browsing Amazon, eBay, car dealerships the little images are low quality but enough to give you a good idea of what the product is. Once you click it, then the better quality images are retrieved.
Advantages of using thumbnails in other type of applications
Web is not the only place this can be used. I worked on an iPad application and we used the same technique. However, instead of clicking the image we were waiting to see if the user will zoom (pinch and zoom) on the image. As soon as the user zoomed in, we would get a higher quality image. If they zoomed in again, we would get even a higher quality image. We had 4 different levels of quality for each image.
In conclusion there are two advantages to using thumbnails:
Faster load (performance)
Bandwidth-smaller size images (especially important to mobile users because data will cost them $$$)
Here is a page with thumbnails. And here are the better quality images of one of the thumbnails.

Force Controller Action to return "Type" as Image and NOT as document

Basically, my view is trying to display both thumbnail image and full size image:
<img src="/Images/GetImage/60?s=1&t=True" class="" style="width: 100px; height: 80px;" data-id="60" data-source="1">
<img src="/Images/GetImage/60?s=1&t=False" class="" style="width: 100px; height: 80px;" data-id="60" data-source="1">
The only thing that changes is the t (thumbnail) boolean value.
When I pass true, the browser http request is interpreted as Type: jpeg
When I pass false, it is interpreted as document
Please check the following printscreen:
How can I really force the Controller Action to return Type as Image and NOT as document?
My actual source code:
public async Task<ActionResult> GetImage(int id, EnumImageSource s, bool t)
{
var backupImagePath = Server.MapPath(Url.Content("~/Content/Images/PhotoNotAvailable.png"));
var originalImagePath = Server.MapPath(Url.Content("~/Content/Images/PhotoNotAvailable.png"));
var finalImagePath = Server.MapPath(Url.Content("~/Content/Images/PhotoNotAvailable.png"));
...
...
...
...
if (model != null)
{
...
...
...
originalImagePath = model.Object.Path;
}
if (t)
{
var extension = System.IO.Path.GetExtension(originalImagePath);
var thumbImagePath = System.IO.Path.ChangeExtension(originalImagePath, null) + "_thumb" + extension;
if (System.IO.File.Exists(thumbImagePath))
{
finalImagePath = thumbImagePath;
}
else
{
if (System.IO.File.Exists(originalImagePath))
{
int width;
int height;
if (ProcessImage.GetDimentionsByImageType(EnumImageSize.Thumbnail, out width, out height))
{
try
{
if (ProcessImage.ResizeImageFile(width, height, originalImagePath, thumbImagePath))
{
finalImagePath = thumbImagePath;
}
}
catch
{
}
}
}
}
}
else
{
if (System.IO.File.Exists(originalImagePath))
{
finalImagePath = originalImagePath;
}
}
var bytes = System.IO.File.ReadAllBytes(finalImagePath);
Response.ContentType = "image/jpeg";
return File(bytes, "image/jpeg");
}
UPDATE #1
As requested by MaKCbIMKo. Yes, if I display the full image next to the thumbnail then both of them are processed as "Image".... but as you can see the way that I am add the "a" html tag is using the same path... however, now it seems that the lightcase.js is somehow processing it as document and not as image, probably by trying to read the "path extension" and match it with image or not... I really think this is the problem now.
<div class="img-wrap">
#if (Model.IsReadOnly == false)
{
<span class="close">×</span>
}
<a href="#(Url.Action("GetImage", "Images", new { area = "", id = i.Id, s = (int)i.ImageSource, t = false }))" data-rel="lightcase:myCollection#(Model.SourceId)" class="showcase">
<img src="#(Url.Action("GetImage", "Images", new {area = "", id = i.Id, s = (int) i.ImageSource, t = true}))" class="" style="width: 100px; height: 80px;" data-id="#i.Id" data-source="#((int)Model.ImageSource)" />
</a>
FULL IMAGE
<img src="#(Url.Action("GetImage", "Images", new {area = "", id = i.Id, s = (int) i.ImageSource, t = false}))" class="" style="width: 100px; height: 80px;" data-id="#i.Id" data-source="#((int)Model.ImageSource)" />
</div>
It seems that the problem was the lightcase.js code....
I just tested a quick change on the source code:
createObject: function () {
var $object;
// Create object
switch (_self.objectData.type) {
....
default:
$object = $(new Image());
$object.attr({
// The time expression is required to prevent the binding of an image load
'src': _self.objectData.url,
'alt': _self.objectData.title
});
break;
And now I have the image displayed as image and not inside the iframe....
This is not the final solution, but at least a proof to where the problem lies.
Ok, from here I know what I can do and on how to tackle this.
I noticed two things about lightcase.js:
-They always use link and not an image. Even if image is shown, it is inside <a> element. So, try to wrap your <img /> with <a>.
-They check urls for ending in some predefined extensions. Check source, from line 114 (typeMapping) and line 752 (_verifyDataType function). It might help if you add dummy query string parameter like:
Images/GetImage/60?s=1&t=True&type=.jpg. You will ignore it server side but might help with lightcase
I can't try it right now, but I hope it helps.
In the past I have had strange issues when returning files with ActionResult specially file encoding Try returning FileContentResult

Problems with Charting Display

I am having problems getting pie charts to display in my views correctly. With the code below, I have confirmed that bytes are being successfully written to the model and passed to the view. I have even confirmed that I can save the pie chart to a PNG file within a directory from the view, but every time I attempt to display the pie chart in the browser, no image is displayed.
You will see that I'm using an Index view with a Partial view for the Pie Chart. The plan is to present multiple partial views into the Index view.
I'm hoping someone can help me get past this. Thanks in advance.
Model:
public byte[] PieChartBytes { get; set; }
public class StatsForPieChart
{
public string dest { get; set; }
public long recordCount { get; set; }
}
Controller:
public ActionResult _DisplayPieChart (model.ViewModel model)
{
ArrayList xSeriesList = new ArrayList();
ArrayList ySeriesList = new ArrayList();
foreach (var item in model.statsforPieChart)
{
xSeriesList.Add(item.dest);
sSeriesList.Add(item.recordCount);
}
model.PieChartBytes = new Chart(width:800, height:600, theme: ChartThem.Blue)
.AddTitle("Title")
.AddLegend()
.AddSeries(
name: "Name",
chartType: "Pie",
xValue: xSeriesList,
yValues: ySeriesList)
.GetBytes("png");
return PartialView(model);
}
Index View:
Html.RenderAction("_DisplayPieChart", new { model = Model });
Pie Chart View:
#{
//the "Save" code is only used to prove the file bytes have been successfully passed and the image is present in the view:
string sImagePath = Server.MapPath("~") + "Content\\" + Guid.NewGuid().ToString + ".png"
WebImage myImage = new WebImage(Model.PieChartBytes);
myImage.Save(sImagePath);
}
<div class="text-center">
<img src="#sImagePath" /> //works in debug mode, but gets blocked on web server - not desired solution.
<img src="#myImage" /> //desired solution, but produces no image.
</div>
Where the image is just a string of bytes and not a file stored on a server anywhere, you need to prefix the bytes like this:
<img src="data:image/png;base64,#myImage" />
This is called a Data URL or Data URI
Additionally, though, I'm not sure you need to use WebImage here. You're already calling GetBytes() on the Chart object. That should return the bytes that you can use to display the image:
<img src="data:image/png;base64,#Model.PieChartBytes" />
Based on #Anonymous3521's comment, this code worked:
Controller:
var base64 = Convert.ToBase64String(Model.PieChartBytes);
var imgSrc = String.Format("data:image/png;base64,{0}", base64);
View:
<img src="#imgSrc" />

Captcha image custom not updating in mvc

All is working well except image not refreshing while changing source using jquery while trying new captcha, there is always needs to refresh page then image is updating.
CSHTML:
<p>
<img id="captchaimage" src="/User/ShowCaptchaImage" />
<span class="icon-f-reset"></span><span>Try New Captcha</span>
</p>
I am using the Custom Captcha class with inherit the ActionResult. and the ExecuteResult as:
C# :
public override void ExecuteResult(ControllerContext context)
{
// Create image code here , i have implemented.
//and add response as:
HttpResponseBase response = context.HttpContext.Response;
response.ContentType = "image/GF";
bmp.Save(response.OutputStream, ImageFormat.Gif);
bmp.Dispose();
g.Dispose();
}
JQUERY:
$(document.body).on("click", ".f-captcha", function () {
$('#captchaimage').attr('src', '/User/ShowCaptchaImage');
});
But i need refresh the page when i am clicking on try new captcha anchor tag.
Try to use a unique string with img source
$(document.body).on("click", ".f-captcha", function () {
var randLetter =Math.floor(Math.random() * 5854553);
$('#captchaimage').attr('src', '/User/ShowCaptchaImage?ver='+randLetter);
});
Hi i struct with same problem but i find solution on net try these these will work for me.
these can be happen because browser get image from catch memory
$(document).ready(function () {
$(".f-captcha").click(function () {
d = new Date();
$("#captchaimage").attr("src", "/User/ShowCaptchaImage?" + d.getTime());
});
});

Categories

Resources