Image won't display MVC5 - asp.net-mvc

Hello evryone (im using MVC5),
i generate image from Chart in Html Helper Extension
public static string GetUrlFromChart(this HtmlHelper helper, Chart chart)
{
lock (obj)
{
string path = HttpContext.Current.Server.MapPath("~/App_Data/graphs/");
string filename = path + Guid.NewGuid() + ".jpg";
chart.ToWebImage("jpg").Save(filename);
return filename;
}
}
by viewmodel i send data to view and i tried to show them to user.
<img src="#Html.GetUrlFromChart(#Model.my_chart)" width="400" height="250"/>
Image generate properly, in correct path, but application cannot show me it,
its only white rectangle
when i copy image source to windows explorer.
i get that image.
but it seems to wont work with
<img></img>
anyone know how to display System.Web.Helpers.Chart like image, or display data like chart ?

Hello mate you should return the image rather than the file path
I don't know about this Chart object so I just change the code to a generic one
change your code to:
public static ActionResult GetUrlFromChart()
{
lock (obj)
{
string path = HttpContext.Current.Server.MapPath("~/App_Data/graphs/");
string filename = path + Guid.NewGuid() + ".jpg";
var image = chart.ToWebImage("jpg");
//save your image.
return File(image.GetBytes(), "image/jpeg");
}
}
in the view:
<img src="#Url.Action("GetUrlFromChart", "Yourcontrollername")"/>

Related

MVC Access Resource image

I want to access and return a resource image from a DLL /connected project.
(Its a file, with build action of Resource). It is not listed in properties/resource as there are hundreds of them in the folder.
The idea is that I can call an image controller.
public ImageResult Display(string resourcePath){
Uri uri = new Uri("pack://application:,,,/ProjectName;component/Images/Vectors/" + resourcePath, UriKind.Absolute);
// What goes here??
}
The problem is i dont know how to turn the URI into an image, in MVC5.
I want to be able to call it from the view. using the url property of the <img> tag
I think you could try WebClient.DownloadData() method to download the image as byte array from specified URI, then convert it to Base64 format with Convert.ToBase64String() and display it on <img> tag using a string property in the viewmodel as src attribute value, below is an example to display the image:
Viewmodel Example
public class ViewModel
{
// other properties
// used to pass image into src attribute of img tag
public string ImageData { get; set; }
}
Controller Action
public ActionResult Display(string resourcePath)
{
Uri uri = new Uri("pack://application:,,,/ProjectName;component/Images/Vectors/" + resourcePath, UriKind.Absolute);
using (var wc = new System.Net.WebClient())
{
// download URI resource as byte array
byte[] image = wc.DownloadData(uri);
// get image extension
string path = string.Format("{0}{1}{2}{3}", uri.Scheme, Uri.SchemeDelimiter, uri.Authority, uri.AbsolutePath);
string extension = System.IO.Path.GetExtension(path).Replace(".", "");
// assign image to viewmodel property as Base64 string format
var model = new ViewModel();
model.ImageData = string.Format("data:image/{0};base64,{1}", extension, Convert.ToBase64String(image));
return View(model);
}
}
View
#model ViewModel
<img src="#Model.ImageData" ... />
Additional note:
If you already know the extension from the resource URI, you could use it directly instead of using Path.GetExtension, here is an example for JPG format:
model.ImageData = string.Format("data:image/jpg;base64,{0}", Convert.ToBase64String(image));
Related issues:
Image to byte array from a url
MVC How to display a byte array image from model
Be sure to register the pack:// scheme as this won't automatically be registered in an MVC app as it is in a WPF app.
In this example code, Blarn0 is a public property in my model class to ensure that the access to the PackUriHelper.UriSchemePack property isn't optimized away when the code is published in Release configuration. I'm sure one can use discards for this very purpose in later versions of C#.
const string scheme = "pack";
if (!UriParser.IsKnownScheme(scheme))
Blarn0 = PackUriHelper.UriSchemePack;

ASP.NET MVC Images secured using createObjectURL in <img> tag

I have an existing ASP.NET MVC application that displays thumbnail images from physical storage connected to the web server. This can also be storage located elsewhere via the file url per the database record.
The image thumbnails are referenced by URL strings (i.e. https://domain/path/file.jpg) in image tags in a for each loop in the view. Also using lazy loading of the image for performance using jquery.lazy.min.js.
Due to the sensitive nature of the images I am required to secure the url of the file to prevent unauthorized access to the images by viewing the page source. The image thumbnail URL’s are provided in a List via the view model passed to the view from the controller.
From what I have been reading the best possible means of securing the URL of the image is to generate a blob:https, or blob:file so that the reference is secured for the current page.
I have been working on trying to accomplish this using (URL || webkit).createObjectURL(file_url) but the problem is that the thumbnail image url is a string and I need to get it into an Object File type.
I see that using and createObjectURL works to secure the image source that is loaded with a result such as this: http://localhost:10480/91733a7a-65fe-4176-979e-82c2fc7148c3" title="Original size: 1635x2623">
My question, in the for each loop to load and display the image tags in the view, is how can I supply the img tag data-src with the file blob instead of the url string? Not sure how to mix the HTML and Javascript to do this.
Any help or direction is greatly appreciated. Thank you.
I think this can help you.I created a function in View(you can do it in back end)
and call it by Image path.Then this function convert your image to Base64String and your address will be secure and any one don't know where is you actual path.
#using System.Drawing
#{
ViewBag.Title = "Home Page";
#helper GetBinayImage(string path)
{
using (Image image = Image.FromFile(path))
{
using (MemoryStream m = new MemoryStream())
{
image.Save(m, image.RawFormat);
byte[] imageBytes = m.ToArray();
// Convert byte[] to Base64 String
string base64String = Convert.ToBase64String(imageBytes);
string imageSrc = string.Format("data:image/gif;base64,{0}", base64String);
<img src="#imageSrc" width="100" height="100" />
}
}
}
}
<div>
#GetBinayImage(#"path/file.jpg")
</div>
When you look at page source you see some thing like this:
And if your path is url you can use some thing like this:
#using System.Drawing
#{
ViewBag.Title = "Home Page";
#helper GetBinayImage(string path)
{
var webClient = new WebClient();
byte[] imageBytes = webClient.DownloadData("http://www.google.com/images/logos/ps_logo2.png");
string base64String = Convert.ToBase64String(imageBytes);
string imageSrc = string.Format("data:image/gif;base64,{0}", base64String);
<img src="#imageSrc" width="100" height="100" />
}
}
<div>
#GetBinayImage(#"https://www.google.com/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png")
</div>

Add PDFObject from already created pdf element

I have a pdf element that I am returning as a string base64 element since it is an MVC Web Application and the files live on a server. I am currently using PDFObject and pdf.js to try and view this PDF in the browser. However, I seem unable to display the PDF, unless I pass a url, which won't work when I put this application in IIS on a server.
So is there a way to have my embedded pdf with the src="{my base 64 string}, and then wrap the PDFObject around that? If not, is there a way, via PDFObject, to use a base64 string instead of a url?
Also, this is in IE 11
UPDATE
Here is my controller
public ActionResult GetPDFString(string instrumentType, string booktype, string book, string startpage, string EndPage)
{
LRS_Settings settings = ctxLRS.LRS_Settings.FirstOrDefault();
string root = settings.ImagePathRoot;
string state = settings.State;
string county = settings.County;
g_filePath = #"\\10.20.170.200\Imaging\GA\075\Daily\" + instrumentType + "\\" + book + "\\";
//g_filePath = #"\\10.15.100.225\sup_court\Imaging\GA\075\Daily\" + instrumentType + "\\" + book + "\\";
byte[] file = imgConv.ConvertTifToPDF(g_filePath, booktype, book, startpage, EndPage);
var ms = new MemoryStream(file);
var fsResult = new FileStreamResult(ms, "application/pdfContent");
return fsResult;
//return imgConv.ConvertTifToPDF(g_filePath, booktype, book, startpage, EndPage);
}
Here is my jquery
var options = {
pdfOpenParams: {
navpanes: 1,
toolbar: 0,
statusbar: 0,
pagemode: 'none',
pagemode: "none",
page: 1,
zoom: "page-width",
enableHandToolOnLoad: true
},
forcePDFJS: true,
PDFJS_URL: "/PDF.js/web/viewer.html"
}
PDFObject.embed("#Url.Action("GetPDFString", "DocumentView", new { instrumentType = ViewBag.instrumentType, BookType = Model.BookType, Book = ViewBag.Book, StartPage = ViewBag.StartPage, EndPage = ViewBag.endPage, style = "height:100%; width100%;" })", "#PDFViewer", options);
The problem is now, instead of showing the PDF inside of #PDFViewer, it is trying to download the file. Could someone please assist me on the final piece to the puzzle. This is driving me crazy.
Have you tried to use just the standard html to do this instead?
Controller Action
public ActionResult GetAttachment(string instrumentType, string booktype, string book, string startpage, string EndPage)
{
var fileStream = new FileStream(Server.MapPath("~/Content/files/sample.pdf"),
FileMode.Open,
FileAccess.Read
);
var fsResult = new FileStreamResult(fileStream, "application/pdf");
return fsResult;
}
In your view
<div id="PDFViewer">
<embed src="#Url.Action("GetAttachment", "DocumentView", new { instrumentType = ViewBag.instrumentType, BookType = Model.BookType, Book = ViewBag.Book, StartPage = ViewBag.StartPage, EndPage = ViewBag.endPage })" width="100%" height="100%" type="application/pdf"></embed>
</div>
Would this suit your requirements rather than using PDFObject?
Be sure to set the content disposition header to inline or the browser will try to download the file rather than render it in the viewport.
See Content-Disposition:What are the differences between "inline" and "attachment"?
As far as PDFObject versus plain HTML, for troubleshooting I always recommend trying static markup (no JS) to display the same PDF. If it works there, the problem may lie with PDFObject (in this case, PDFObject's handling of Base64 strings). If the PDF is not properly rendered via plain markup, the issue probably lies with your file/Base64.
You can grab a copy of static markup from the PDFObject static markup generator: http://pdfobject.com/generator
(I should add that I can't speak to PDF.js' handling of Base64 strings...)

Convert HttpPostBasicFile to Image in MVC

I get a picture by uploading and I want to convert it to image file without save it.
how can I do it?
public HttpPostedFileBase BasicPicture { get; set; }
var fileName = Path.GetFileName(BasicPicture.FileName);
// store the file inside ~/App_Data/uploads folder
var path = Path.Combine(Server.MapPath("~/App_Data/uploads"), fileName);
BasicPicture.SaveAs(path);
By this code I can save the picture on the server but I want convert it to image
like
Image img=(Image) BasicPicture;
but it doesn't work.
You could use the FromStream method:
using (Image img = Image.FromStream(BasicPicture.InputStream))
{
... do something with the image here
}
You can also convert HttpPostedFileBase to WebImage (which gives you more API - like method Resize):
public ActionResult SaveUploadedImage(HttpPostedFileBase file)
{
if(file != null)
{
var image = new System.Web.Helpers.WebImage(file.InputStream);
var path = Path.Combine(Server.MapPath("~/App_Data/uploads"), file.FileName);
image.Save(path);
}
return View();
}
With out knowing exactly what you are doing and why i can give a full intelligent answer.
Personally i would use something like this to open an image. You have saved the image to your server, so instead of casting why not new up a new image? the end result is the same!
WebImage webImage = new WebImage(path);

ASP.NET MVC Dynamically generated image URLs

I have an ASP.NET MVC application where I am displaying images.
These images could be located on the file system or inside a database. This is fine as I can use Url.Action in my image, call the action on my controller and return the image from the relevant location.
However, I want to be able to support images stored in Amazon S3. In this case, I don't want my controller action to return the image, it should instead generate an image URL for Amazon S3.
Although I could just perform this logic inside my view e.g.
<%if (Model.Images[0].ImageLocation == ImageLocation.AmazonS3) {%>
// render amazon image
I need to ensure that the image exists first.
Essentially I need to pass a size value to my controller so that I can check that the image exists in that size (whether it be in the database, file system or amazon s3). Once I am sure that the image exists, then I return the URL to it.
Hope that makes sense,
Ben
Try the following approach.
A model class for an image tag.
public class ImageModel
{
public String Source { get; set; }
public String Title { get; set; }
}
Helper
public static String Image(this HtmlHelper helper, String source, String title)
{
var builder = new TagBuilder("img");
builder.MergeAttribute("src", source);
builder.MergeAttribute("title", title);
return builder.ToString();
}
View with Model.Images of type IEnumerable<ImageModel>
...
<%= Html.Image(Model.Images[0].Source, Model.Images[0].Title) %>
Action
public ActionResult ActionName(/*whatever*/)
{
// ...
var model = ...;
//...
var model0 = ImageModel();
if (Image0.ImageLocation == ImageLocation.AmazonS3)
model0.Source = "an amazon url";
else
model0.Source = Url.Action("GetImageFromDatabaseOrFileSystem", "MyController", new { Id = Image0.Id });
model0.Title = "some title";
model.Images.Add(model0);
// ...
return View(model);
}
An action is a kind of a pseudo code, however the idea should be clear.
After several iterations I have come up with a workable solution, although I'm still not convinced its the best solution.
Originally I followed Anton's suggestion and just set the image url accordingly within my controller action. This was simple enough with the following code:
products.ForEach(p =>
{
p.Images[0].Url = _mediaService.GetImageUrl(p.Images[0], 200);
});
However, I soon found that this approach did not give me the flexibility I needed. Often I will need to display images of different sizes and I don't want to use properties of my model for this such as Product.FullSizeImageUrl, Product.ThumbnailImageUrl.
As far as "Product" is concerned it only knows about the images that were originally uploaded. It doesn't need to know about how we manipulate and display them, or whether we are caching them in Amazon S3.
In web forms I might use a user control to display product details and then use a repeater control to display images, setting the image urls programatically in code behind.
I found that the use of RenderAction in ASP.NET MVC gave me similar flexibility:
Controller Action:
[ChildActionOnly]
public ActionResult CatalogImage(CatalogImage image, int targetSize)
{
image.Url = _mediaService.GetImageUrl(image, targetSize);
return PartialView(image);
}
Media Service:
public MediaCacheLocation CacheLocation { get; set; }
public string GetImageUrl(CatalogImage image, int targetSize)
{
string imageUrl;
// check image exists
// if not exist, load original image from store (fs or db)
// resize and cache to relevant cache location
switch (this.CacheLocation) {
case MediaCacheLocation.FileSystem:
imageUrl = GetFileSystemImageUrl(image, targetSize);
break;
case MediaCacheLocation.AmazonS3:
imageUrl = GetAmazonS3ImageUrl(image, targetSize);
break;
default:
imageUrl = GetDefaultImageUrl();
break;
}
return imageUrl;
}
Html helper:
public static void RenderCatalogImage(this HtmlHelper helper, CatalogImage src, int size) {
helper.RenderAction("CatalogImage", "Catalog", new { image = src, targetSize = size });
}
Usage:
<%Html.RenderCatalogImage(Model.Images[0], 200); %>
This now gives me the flexibility I require and will support both caching the resized images to disk or saving to Amazon S3.
Could do with some url utility methods to ensure that the generated image URL supports SSL / virtual folders - I am currently using VirtualPathUtility.
Thanks
Ben
You can create a HttpWebRequest to load the image. Check the header in the response, if it's 200 that means it was successful, otherwise something went wrong.

Resources