Generate a 1x1 white gif as a Stream in c# - c#

I would like to return an image as an ActionResult from an MVC2 controller. This image is a 1x1 white pixel (for a tracking application). I do not want to reference an image on the disk or in a database. I would like to generate the image in my method and then return it from the controller action.
Any one know how to generate a 1x1 white image that can be passed into a FileStreamResult for returning from the controller action?

Copied from Daniel Ballinger's FishOfPrey.com:
Response.Clear();
string content = #"R0lGODlhAQABAPcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAP8ALAAAAAABAAEAAAgEAP8FBAA7";
Response.ContentType = "image/gif";
Response.BinaryWrite(System.Convert.FromBase64String(content));
Response.End();
I don't speak C#, but if you use this string in your program, you can save storing and accessing one extra file on disk.

Avoid the use of Response.End();, as used in eumiro's answer, is not a good idea, read more here: http://support2.microsoft.com/kb/312629
Insted, to avoid unnecessary ThreadAbortException, change your Action to a FileContentResult like this:
public FileContentResult Track(Guid id)
{
//do tracking stuff ....
//return empty gif
const string clearGif1X1 = "R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==";
return new FileContentResult(
Convert.FromBase64String(clearGif1X1), "image/gif");
}
also for tracking purposes remember to add some kind of NoCache attribute

I prefer to use images with extensions so this is what I use:
// URL is /mailers/images/pixel123.gif
// where 123 is the tracking number
[ActionName("images")]
public ActionResult Pixel(string id)
{
int trackingID = int.Parse(id.Substring("pixel".Length, id.Length - "pixel.gif".Length));
// do something in database
string trackingPixel = #"R0lGODlhAQABAPcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAP8ALAAAAAABAAEAAAgEAP8FBAA7";
return File(System.Convert.FromBase64String(trackingPixel), "image/gif");
}

Related

How do I convert a byte array back to an image consumable by a view in asp net core?

I'm converting uploaded images to byte arrays like so:
private byte[] GetByteArrayFromImage(IFormFile file)
{
using (var target = new MemoryStream())
{
file.CopyTo(target);
return target.ToArray();
}
}
When looking for a solution to convert back to an image that I can show on-screen in an asp.net core view, I find this one:
MemoryStream ms = new MemoryStream(myByteArray);
Image image= Image.FromStream(ms);
But it doesn't work. The only reference I get for Image is using static System.Net.Mime.MediaTypeNames; and there's no FromStream method for this.
I think my main issue here is that I don't actually know what type I need to be converting the byte array into so I can display it on a page?!
edit do I actually just need to convert it back to an IFormFile type?
This was really simple. I just wasn't sure what to look for. Say I have an ImageDisplayModel with various properties, one of which should be a string ImageSource:
ImageDisplayModel.ImageSource = "data:image/gif;base64," + Convert.ToBase64String(myByteArray);
And then in a view:
<img src="Model.ImageSource" />

How to properly return a PDF inside a JSON response?

I need to return two PDF file's inside my WebApi 2 response, actually i'm doing it by simply sending the pdf file as a Base64 string but my question was if the approach was correct or if there is a better way to do so..
Here is my constructor which my Api returns:
public class DCW
{
public string numdoc { get; set; }
public string pdf { get; set; }
public string pdf_regalo { get; set; }
public string Base64(string path)
{
// Method to convert pdf to Base64
byte[] bytes = File.ReadAllBytes(path);
string file = Convert.ToBase64String(bytes);
return file;
}
}
And here is how my controller look's like:
[Route("api/[controller]")]
public class DriverController : Controller
{
[HttpPost]
public DCW Post([FromBody]Scontrino scontrino)
{
DCW dcw = new DCW();
string pdf = dcw.Base64("C:/users/imytyuk/Desktop/TEST/XXX01_731378.pdf");
string pdf_regalo = dcw.Base64("C:/users/imytyuk/Desktop/TEST/XXX01_731378_regalo.pdf");
dcw.numdoc = "5454835";
dcw.pdf = pdf;
dcw.pdf_regalo = pdf_regalo;
return dcw;
}
}
Actually the response is the following:
{
"numdoc": "5454835",
"pdf": "XAGCTiT45cuco3YWQ6Ckz9e1//f0nr1NYb8f9crD26pyfKa4QBrqOsjf0d8vsaJmn1if6BbiRtHkKZW5kc3RyZWFtCmVuZG2QJ4G83q5nqMbS1sNHnZsr7uBPMd8Bkdbr4AplbmRzdHJlYW0KZW5kb2JqCjE5IDAgb2JqCjc3MAplbmRvYmoKMjAgMCBvYmoKPDwvRmlsdGVyL0ZsYXRlRGVjb2RlL1R5cGUvWFJlZi9XWzEgMADSDSAeM2RTM0MzBCOTZCRTA0QUM4OTNFREJFNT5dL0RlY29kZVBhcm1zPDwvQ29sdW1ucyA1L1ByZWRpY3RvciAxMj4+L0xlbmd0aCA5NCAgICAgICAgPj4Kc3RyZWFtCnicNcuxDYAwDETR8wVFoUdiCCqGYhMGYAyo2IAx2CVEwdgImqfTl00AqiSStLSN/Bo+NZxe6ghQkE1Ng4lyeKn9d6nUZsNNcPV+7Yh/jxMKIbN/SeeGxYXtB9mvFuAKZW5kc3RyZWFtCmVuZG9iagpzdGFydHhyZWYKMjk4NQolJUVPRgo=",
"pdf_regalo": "JV9IKNiAwIG9iago8PC9MZW5ndGggNSAwIFIvRmlsdGVyL0ZsYXRlRGVjb2RlPj4Kc3RyZWFtCniclVZdb9pIFFWcAWwTYQOxIRCSaQutHWA6ng+DSDvmyXt7hPW+3DqolUXvbv77WDiSk2TIWQPB/n3HOvz9zxd/uXjf3xN4ojhjf/2BRv/rAZTwmLGU4iQTiF+a/2Y3BhXKIwSoJWmNDAaBsXHbNjIit77oZfNp/sXzf2n/b3OjKmiFIMqzR+JbvKtj3HdbItMvthxNLAGAyvPeT7o/HN5Maf3o7OkEYxoTBWKnkl7MH50sABP5aSi5SQ8lZM74DHNwcGAJZqQ6KBaR5WysiALH5wsRNl2uVy5MNzCyKt7A5wRqcMJ1fdr8CBIJhERyUn0IzRrRUEUNNrVGrlkCfrcj+5qXXvCmB5rgBoT0kH/4KdqRmCESr/UyKi8PJrTOU95Kh0N9IkXBK36bIu+wtiDq++lN1tTD/uz/njsuN5b611dUpJBF5Q63MF8Ma87/KBMpGd9N8zCXs+ly7XjuBE4epltWeFm5D6gnc+3D866ztxML0Rz3TXAzS4S6rwHm7MrUkNkzbmL1itY7+VHJgvcxkQ1wp3IVAPd7LD8Kjjnzx9Tfcjzy7MsZrOQnuxQOhFO6IvgQ0icRt9nYRYIsi76ZucDuh/Khb/wJ9PR9DZuqrkGL1LrFUL+ZODPBznhwRUmcfn//Lv9yDHHXyj+mt8HsrDeE3xgls/lXdCIYhWY0IeJCkzG2rAcFRWHfyfyZaCnsgSKnwCKKrAQqgkEnOCFfV6U7gZaSvdA8RNAUQXmSg+A/wMR9mz2CmVuZHN0cmVhbQplbmRvYmoKNSAwIG9iago5MDUKZW5kb2JqCjkgMCBvYmoKPDwvVGl0bGUgKERPQ1VNRU5UTyBDT01NRVJDSUFMRSBESSBWRU5ESVRBICRSZXZpc2lvbjogMS4wICQpCi9DcmVhdGlvbkRhdGUgKEQ6MjAyMDA0MDcxMTM0NTQrMDInMDAnKQovUHJvZHVjZXIgKFBERmxpYiBQZXJzb25hbGl6YXRpb24gU2VydmVyIDkuMC40IFwoSkRLIDEuNi9MaW51eC14ODZfNjRcKSkKPj4KZW5kb2JqCjEyIDAgb2J="
}
Short answer is no. It's a legit way to transfer files, but there are several cons:
Base64 encoding adds overhead in space due to its text nature
In your approach server must load entire file into the memory and make actual conversion to base64 that can be avoided
In your approach you force browser to load entire file into the memory (actually it has to keep entire request), when client receives base64 encoded file, only way to construct download link is to manipulate with given base64 encoded string, something like href="data:...;base64,asdasd or using browser api.
To fix this I recommend you to create separate GET method's in your controller for each files and rewrite original method such that it will provide necessary info to construct download link in browser to the newly added methods, it might be just relative link to controller method instead of file content. In GET method you also suppose to use
Controller.File(Stream, String, String) and path there FileStream to target file.
Of-course there might be different cases. And sometimes it's necessary to load entire file as base64 to the client browser, for example: cropping images, digital signatures. But if there is any possibility to avoid this it must be avoided.

Use a System.Drawing.Image in an HTML tag

I have a potentially easy question. I have an image stored in a database, I then used a C# method in my application that gets that image and stores it in a custom class that looks like this:
public class MyImage
{
public System.Drawing.Image myImageFromDB;
public string imageName;
public int imageNumberInCollection;
}
My question is this: Can I/How can I use the image from this class in an HTML image tag? I have attempted the following but it just returns a box with a red X in it:
//myImageFromDBCollection is a list of MyImage objects
foreach(var ind in myImagesFromDBCollection)
{
table += String.Format("<image src={0} />", ind.myImageFromDB);
}
Any ideas on what I am doing wrong?
I ended up going with Brads Method of solving this (See the comment under the question) I ended up creating a method that takes in a System.Drawing.Image and converts it to a byte array then encode that byte array to get the image. The code looks like the following:
byte[] imgBytes = turnImageToByteArray(ind.ind.myImageFromDB);
string imgString = Convert.ToBase64String(imgBytes);
table += String.Format("img src=\"data:image/Bmp;base64,{0}\">", imgString);
private byte[] turnImageToByteArray(System.Drawing.Image img)
{
MemoryStream ms = new MemoryStream();
img.Save(ms, System.Drawing.Imaging.ImageFormat.Bmp);
return ms.ToArray();
}
Currently this works for my purposes so thank you to everyone and their suggestions, as always everyone comes though and helps :-)
Images can be served using generic handlers (ashx files):
public class StickerHandler : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = "image/png";
context.Response.Cache.SetCacheability(HttpCacheability.Public);
context.Response.BufferOutput = false;
//TODO: link your MyImage to iSource using imageId query parameter...
Image iSource = null;
MemoryStream ms = new MemoryStream();
iSource.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
byte[] data = ms.ToArray();
ms.Dispose();
g.Flush();
g.Dispose();
iSource.Dispose();
context.Response.BinaryWrite(data);
}
public bool IsReusable
{
get
{
return true;
}
}
}
More about generic handlers can be found here:
http://msdn.microsoft.com/en-us/library/bb398986(v=vs.100).aspx
Inside your image:
<img src='StickerHandler.ashx?img=imageId' />
Happy coding!
If I were you, I'd keep image files on disk, and just have the image filenames in your db.
If you're having a problem with your image formatting, than just look at your source and make sure it's correct.
If you have to store your images in the database, a simple way to view them would be to use an image handler.
Basically, you can create an ASHX handler which accepts a query string that is the Image ID in the database and returns the image content along with the correct mime type. This is quite simple to do in C#.
You can then point the <img /> tag to the handler with the specified ID. Something like
table += String.Format("<image src='/ViewImage.ashx?id={0}' />", ind.myImageId);
Here is a basic tutorial to get you started.
A common performance improvement would be to cache the images on disk within the handler.

How should I return an Image from a controller action c# asp.net-mvc-2?

I am building images from a byte[] like below.
public FileContentResult GetEmployeeImage(int empId)
{
MemoryStream ms = new MemoryStream(byteArray);
Image returnImage = Image.FromStream(ms);
return returnImage;//How should i return this image to be consumed by javascript.
}
I want to return this image to the browser via a controller action method, so as it can be consumed by my javascript code and displayed in the browser. How should I do this?
You don't need to create an image object; you just want to return the raw data.
The browser will read the raw data into an image.
return File(byteArray, "image/png");
Obviously, you need to pass the correct content type, depending on what image format is in the byte array.

Load image to ReportView dynamically

My name is Ed and i need load image from ReportView dinamic.How i can do this?
I work windows forms,c# 3.0 and linq to sql, i need load image to my reports dinamic.
Thanks.
I'm assuming that you are using the Microsoft Report Viewer Component from C# and you want to add an image to the report dynamically.
This is certainly possible, you need to create a class with a byte[] property that represents the serialized bitmap.
class ReportImage {
public byte[] Image {get;set;}
// Other stuff here if you want...
}
Set the property of this object the a 24 bit per pixel serialized version of your Bitmap (i.e. save your bitmap to a MemoryStream, then call MemoryStream.ToArray()). You must use 24 bits per pixel, and the format you save to must be BMP, this seems to be required in the Report Viewer.
You can then bind to the Object Data Source, (see the MSDN documentation for details on binding to Objects, also see the example here). Use the Image item to display your image in the report.
The limitation is that the images in your report must be fixed size. You'll have to resample the images beforehand to fit them in, or, as Jon suggests, dynamically create the RDLC file for the report.
This answer is very helpful (it got me past having little "broken image" boxes on my report), but a little misleading.
It is, strictly speaking, NOT a requirement that the "image" (which is actually a byte array) be a BMP format. In a test project I was able to read jpeg files from disk (i.e. File.ReadAllBytes(filename); ) and add the resulting byte arrays to a byte[] property in a List of "rptrow" (where rptrow is a object that represents all the data for one row in a report table). The images on the report had the MIMEType set to "image/jpeg" and a Source property of "Database". I also noticed that it did not matter what MIMEType I used as long as something was specified, (i.e. not blank).
I was in a hurry, so I didn't even consider checking the statement that it had to be a 24bpp image.
Simplified rptobj:
public class rptobj
{
public string FileName { get; set; }
public byte[] Photo { get; set; }
private List<rptobj> photos;
public List<rptobj> GetList()
{
if (photos == null)
{
photos = LoadPhotos();
}
return photos;
}
private List<rptobj> LoadPhotos()
{
var rslt = new List<rptobj>();
byte[] rawData;
var path = HttpContext.Current.Server.MapPath(#"~\images");
DirectoryInfo di = new DirectoryInfo(path);
FileSystemInfo[] fis = di.GetFileSystemInfos("*.jpg");
foreach(var fi in fis){
rawData = File.ReadAllBytes(string.Format(#"{0}\{1}", path, fi.Name ));
rslt.Add(new rptobj() { Photo = rawData, FileName = fi.Name });
}
return rslt;
}
}
Short answer is that you cannot do this, at least not with the built in report viewer functions.
However, if you are sure you want to do this, you can attempt to dynamically create RDLC files. If you create your RDLC files dynamically, you can dynamically add images to the reports.
You can find some sample code on how to create RDLC files dynamically here.

Categories

Resources