I'm at my wits end here.
I've a HTTP Handler (ImageHandler.ashx) that sends down images (resized), its a standard HTTP handler (tried this with Reusable true and false) that uses the Image.GetThumbnailImage to resize and return the thumbnail.
I've an asp Datalist control which has a table with a html image control.
<asp:DataList ID="listImg" runat="server" RepeatColumns="4" RepeatDirection="Horizontal"
ShowFooter="false" ShowHeader="false">
<ItemTemplate>
<table width="220px">
<tr width="100%">
<td>
<img src="Scripts/ImageHandler.ashx?width=125&image=Upload/<%# DataBinder.Eval(Container.DataItem, "photo") %>"
</td>
</tr>
</table>
</ItemTemplate>
</asp:DataList>
As you can see the parameters the Handler needs are the width and the Image path.
This Datalist is bound to a datatable (ImageData) which provides the list of images to be displayed.
Well all makes sense so far, now here is the issue - Say I'm loading 5 images, i.e. my ImageData DataTable has 5 rows, it is a given that only 3-4 images will be displayed, the remaining ones just come up with a red X, like when you've no image. Now if you look at the code and navigate to the image src like -
http://localhost:3540/Scripts/ImageHandler.ashx?width=150&image=Upload/Test123.jpg
you'll see the image, they're all there no missing images. Reload and they're back.
I ran this in Firefox and opened up Firebug and when I looked through the Images tab, ALL the images were returned according to Firebug (Status 200 OK and I see the Image in the Response tab), it's like the Webserver just does not display some of them. Note that it is NOT always the images that took the longest to process/load that were missing, its some random ones.
What could be going on here?
Thank you.
EDIT 1- Adding the Handler Code (original), we inherited this code. I've removed Caching from the code here, but FYI thumbnails once generated are cached.
public class ImageHandler : IHttpHandler{
public int _width;
public int _height;
public int _percent;
public string imageURL;
public void ProcessRequest(HttpContext context)
{
try
{
Bitmap bitOutput;
string appPath = Convert.ToString(System.Configuration.ConfigurationManager.AppSettings["ImagePath"]);
String strArquivo = appPath + context.Request.QueryString["image"].Replace("/", "\\");
if (!(String.IsNullOrEmpty(context.Request["width"])))
{
Bitmap bitInput = GetImage(context);
if (SetHeightWidth(context, bitInput))
{ bitOutput = ResizeImage(bitInput, _width, _height, _percent); }
else { bitOutput = bitInput; }
context.Response.ContentType = "image/jpeg";
bitOutput.Save(context.Response.OutputStream, System.Drawing.Imaging.ImageFormat.Jpeg);
}
return;
}
catch (Exception ex) { /*HttpContext.Current.Response.Write(ex.Message);*/ }
}
/// <summary>
/// Get the image requested via the query string.
/// </summary>
public Bitmap GetImage(HttpContext context)
{
try
{
if (context.Cache[("ImagePath-" + context.Request.QueryString["image"])] == null)
{
string appPath = Convert.ToString(System.Configuration.ConfigurationManager.AppSettings["ImagePath"]);
appPath = appPath + context.Request.QueryString["image"].Replace("/", "\\");
Bitmap bitOutput;
imageURL = appPath;
bitOutput = new Bitmap(appPath);
return bitOutput;
}
else
{
return (Bitmap)context.Cache[("ImagePath-" + context.Request.QueryString["image"])];
}
}
catch (Exception ex) { throw ex; }
}
/// <summary>
/// Set the height and width of the handler class.
/// </summary>
public bool SetHeightWidth(HttpContext context, Bitmap bitInput)
{
try
{
double inputRatio = Convert.ToDouble(bitInput.Width) / Convert.ToDouble(bitInput.Height);
if (!(String.IsNullOrEmpty(context.Request["width"])) && !(String.IsNullOrEmpty(context.Request["height"])))
{
_width = Int32.Parse(context.Request["width"]);
_height = Int32.Parse(context.Request["height"]);
return true;
}
else if (!(String.IsNullOrEmpty(context.Request["width"])))
{
_width = Int32.Parse(context.Request["width"]);
_height = Convert.ToInt32((_width / inputRatio));
if (_width == 400 &&_height > 500)
{
_height = 500;
_width = Convert.ToInt32(500 * inputRatio);
}
else if (_width == 125 && _height > 200)
{
_height = 200;
_width = Convert.ToInt32(200 * inputRatio);
}
return true;
}
else if (!(String.IsNullOrEmpty(context.Request["height"])))
{
_height = Int32.Parse(context.Request["height"]);
_width = Convert.ToInt32((_height * inputRatio));
return true;
}
else if (!(String.IsNullOrEmpty(context.Request["percent"])))
{
_height = bitInput.Height;
_width = bitInput.Width;
_percent = Int32.Parse(context.Request["percent"]);
return true;
}
else
{
_height = bitInput.Height;
_width = bitInput.Width;
return false;
}
}
catch (Exception ex) { throw ex; }
}
/// <summary>
/// Resizes bitmap using high quality algorithms.
/// </summary>
public static Bitmap ResizeImage(Bitmap originalBitmap, int newWidth, int newHeight, int newPercent)
{
try
{
if (newPercent != 0)
{
newWidth = Convert.ToInt32(originalBitmap.Width * (newPercent * .01));
newHeight = Convert.ToInt32(originalBitmap.Height * (newPercent * .01));
}
Bitmap inputBitmap = originalBitmap;
Bitmap resizedBitmap = new Bitmap(newWidth, newHeight, PixelFormat.Format64bppPArgb);
Graphics g = Graphics.FromImage(resizedBitmap);
g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
g.CompositingMode = System.Drawing.Drawing2D.CompositingMode.SourceCopy;
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
Rectangle rectangle = new Rectangle(0, 0, newWidth, newHeight);
g.DrawImage(inputBitmap, rectangle, 0, 0, inputBitmap.Width, inputBitmap.Height, GraphicsUnit.Pixel);
g.Dispose();
return resizedBitmap;
}
catch (Exception ex) { throw ex; }
}
public bool IsReusable
{
get
{
return true;
}
}}
EDIT 2 If someone wishes to test this whole thing out, here is the code that picks up images at random from a predefined folder to create the DataTable (ImageData) that the aspDataList (listImg) is bound to -
System.IO.DirectoryInfo dirInfo = new System.IO.DirectoryInfo(Server.MapPath("Upload"));
System.IO.FileInfo[] files = dirInfo.GetFiles();
int fileCount = files.Length;
System.Data.DataTable ImageData = new System.Data.DataTable();
System.Data.DataColumn dCol = new System.Data.DataColumn("photo");
ImageData.Columns.Add(dCol);
System.Random rnd = new Random();
int nxtNumber = 0;
System.Data.DataRow dRow = null;
string fileName = string.Empty;
for (int i = 0; i < 20; i++)
{
dRow = ImageData.NewRow();
nxtNumber = rnd.Next(fileCount);
while (!files[nxtNumber].Extension.Equals(".jpg"))
{
nxtNumber = rnd.Next(fileCount);
}
fileName = files[nxtNumber].Name;
dRow["photo"] = fileName;
ImageData.Rows.Add(dRow);
}
listImg.DataSource = ImageData;
listImg.DataBind();
try to encode querystring of url, for ex:
http://localhost:3540/Scripts/ImageHandler.ashx?width=150&image=Upload/Test123.jpg
urlencode to
http://localhost:3540/Scripts/ImageHandler.ashx?width%3D150%26image%3DUpload%2FTest123.jpg
I presume your actual code includes the /> at the end of the img tag???
If not you could try adding this first and retesting.
Not really an answer but you could try changing the img tag to an asp:Label and displaying the filename as text rather than displaying the image just to see if the datatable is being constructed correctly. As you are able to see the images when accessing the image handler directly I would say it has something to do with the datatable construction in the codebehind.
When ever I have done anything similar I usually store the images in the SQL DB and use the image handler to return the image with the record id in the query string. This means you are returning a existing table of records rather than having to create one based on the contents of a folder.
Well here is the funny thing - the same code on the server behaves in a more predictable manner, I may still have a couple of missing images, but now it is like 1 missing from say 30-40 on average versus 1 from every 5 in my local environment.
Since these requests were asynchronous could it have something to do with the actual cpu of the machine it was running on, the server was just better adapted to deal with multiple requests versus my measly laptop?
Either ways I've modified the code, so at this point there is no re-sizing involved, the handler code just fetches re-sized images and all is well at this point.
Thank you all for your inputs.
Related
I am working on a project where i want to generate Bar-code based on an user-ID. I need a code which can generate bar-code and also is encrypted. I have found a few codes but they do not seem very helpful. Thank you in advance for help. i have tried this code but it does not provide me the barcode image.
`private void Page_Load(object sender, System.EventArgs e)
{
// Get the Requested code to be created.
string Code = Request["code"].ToString();
// Multiply the lenght of the code by 40 (just to have enough width)
int w = Code.Length * 40;
// Create a bitmap object of the width that we calculated and height of 100
Bitmap oBitmap = new Bitmap(w,100);
// then create a Graphic object for the bitmap we just created.
Graphics oGraphics = Graphics.FromImage(oBitmap);
// Now create a Font object for the Barcode Font
// (in this case the IDAutomationHC39M) of 18 point size
Font oFont = new Font("IDAutomationHC39M", 18);
// Let's create the Point and Brushes for the barcode
PointF oPoint = new PointF(2f, 2f);
SolidBrush oBrushWrite = new SolidBrush(Color.Black);
SolidBrush oBrush = new SolidBrush(Color.White);
// Now lets create the actual barcode image
// with a rectangle filled with white color
oGraphics.FillRectangle(oBrush, 0, 0, w, 100);
// We have to put prefix and sufix of an asterisk (*),
// in order to be a valid barcode
oGraphics.DrawString("*" + Code + "*", oFont, oBrushWrite, oPoint);
// Then we send the Graphics with the actual barcode
Response.ContentType = "image/jpeg" ;
oBitmap.Save (Response.OutputStream, ImageFormat.Jpeg);
}`
Check out this link it is a simple code 39 barcode display which supports a header and footer, printing, saving, and is pretty well customizable. For the encryption part you will have to encrypt your message before converting it to a barcode.
From the link.
Using the code The code is very simple to use, just plop the control
onto a form and you are ready to start customizing it via the
Properties window or through your code. In addition to the
properties, there are also two public functions of interest: public
void Print() This function will display a print dialog and then print
the contents of the control to the selected printer. public void
SaveImage(string filename) This function will save the contents of the
control to a bitmap image specified by filename.
http://www.codeproject.com/Articles/10344/Barcode-NET-Control
Please try Following Code you have to add "FREE3OF9.TTF" font file in your code
Default.aspx.cs code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.IO;
using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Text;
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
////GenerateBarCode.GenerateBarCodes("dfdfdf", Label1);
GenerateBarCode();
}
}
private void GenerateBarCode()
{
WSBarcodeGenerator.BarCodeGenerator barCodeGen = new WSBarcodeGenerator.BarCodeGenerator();
int barSize = 30;
System.Byte[] imgBarcode =Code39("123456", barSize, true, "Centralbiz...");
MemoryStream memStream = new MemoryStream(imgBarcode);
Bitmap bitmap = new Bitmap(memStream);
bitmap.Save(memStream, ImageFormat.Png);
var base64Data = Convert.ToBase64String(memStream.ToArray());
imgBar.Attributes.Add("src", "data:image/png;base64," + base64Data);
//Response.Write(bitmap);
//var base64Data = Convert.ToBase64String(memStream.ToArray());
//imgBar.Attributes.Add("src", "png");
}
public byte[] Code39(string code, int barSize, bool showCodeString, string title)
{
Code39 c39 = new Code39();
// Create stream....
MemoryStream ms = new MemoryStream();
c39.FontFamilyName = "Free 3 of 9";
c39.FontFileName = Server.MapPath("FREE3OF9.TTF");
c39.FontSize = barSize;
c39.ShowCodeString = showCodeString;
if (title + "" != "")
c39.Title = title;
Bitmap objBitmap = c39.GenerateBarcode(code);
objBitmap.Save(ms, ImageFormat.Png);
//return bytes....
return ms.GetBuffer();
}
}
public class Code39
{
private const int _itemSepHeight = 3;
SizeF _titleSize = SizeF.Empty;
SizeF _barCodeSize = SizeF.Empty;
SizeF _codeStringSize = SizeF.Empty;
#region Barcode Title
private string _titleString = null;
private Font _titleFont = null;
public string Title
{
get { return _titleString; }
set { _titleString = value; }
}
public Font TitleFont
{
get { return _titleFont; }
set { _titleFont = value; }
}
#endregion
#region Barcode code string
private bool _showCodeString = false;
private Font _codeStringFont = null;
public bool ShowCodeString
{
get { return _showCodeString; }
set { _showCodeString = value; }
}
public Font CodeStringFont
{
get { return _codeStringFont; }
set { _codeStringFont = value; }
}
#endregion
#region Barcode Font
private Font _c39Font = null;
private float _c39FontSize = 12;
private string _c39FontFileName = null;
private string _c39FontFamilyName = null;
public string FontFileName
{
get { return _c39FontFileName; }
set { _c39FontFileName = value; }
}
public string FontFamilyName
{
get { return _c39FontFamilyName; }
set { _c39FontFamilyName = value; }
}
public float FontSize
{
get { return _c39FontSize; }
set { _c39FontSize = value; }
}
private Font Code39Font
{
get
{
if (_c39Font == null)
{
PrivateFontCollection pfc = new PrivateFontCollection();
pfc.AddFontFile(_c39FontFileName);
FontFamily family = new FontFamily(_c39FontFamilyName, pfc);
_c39Font = new Font(family, _c39FontSize);
}
return _c39Font;
}
}
#endregion
public Code39()
{
_titleFont = new Font("Arial", 10);
_codeStringFont = new Font("Arial", 10);
}
#region Barcode Generation
public Bitmap GenerateBarcode(string barCode)
{
int bcodeWidth = 0;
int bcodeHeight = 0;
// Get the image container...
Bitmap bcodeBitmap = CreateImageContainer(barCode, ref bcodeWidth, ref bcodeHeight);
Graphics objGraphics = Graphics.FromImage(bcodeBitmap);
// Fill the background
objGraphics.FillRectangle(new SolidBrush(Color.White), new Rectangle(0, 0, bcodeWidth, bcodeHeight));
int vpos = 0;
// Draw the title string
if (_titleString != null)
{
objGraphics.DrawString(_titleString, _titleFont, new SolidBrush(Color.Black), XCentered((int)_titleSize.Width, bcodeWidth), vpos);
vpos += (((int)_titleSize.Height) + _itemSepHeight);
}
// Draw the barcode
objGraphics.DrawString(barCode, Code39Font, new SolidBrush(Color.Black), XCentered((int)_barCodeSize.Width, bcodeWidth), vpos);
// Draw the barcode string
if (_showCodeString)
{
vpos += (((int)_barCodeSize.Height));
objGraphics.DrawString(barCode, _codeStringFont, new SolidBrush(Color.Black), XCentered((int)_codeStringSize.Width, bcodeWidth), vpos);
}
// return the image...
return bcodeBitmap;
}
private Bitmap CreateImageContainer(string barCode, ref int bcodeWidth, ref int bcodeHeight)
{
Graphics objGraphics;
// Create a temporary bitmap...
Bitmap tmpBitmap = new Bitmap(1, 1, PixelFormat.Format32bppArgb);
objGraphics = Graphics.FromImage(tmpBitmap);
// calculate size of the barcode items...
if (_titleString != null)
{
_titleSize = objGraphics.MeasureString(_titleString, _titleFont);
bcodeWidth = (int)_titleSize.Width;
bcodeHeight = (int)_titleSize.Height + _itemSepHeight;
}
_barCodeSize = objGraphics.MeasureString(barCode, Code39Font);
bcodeWidth = Max(bcodeWidth, (int)_barCodeSize.Width);
bcodeHeight += (int)_barCodeSize.Height;
if (_showCodeString)
{
_codeStringSize = objGraphics.MeasureString(barCode, _codeStringFont);
bcodeWidth = Max(bcodeWidth, (int)_codeStringSize.Width);
bcodeHeight += (_itemSepHeight + (int)_codeStringSize.Height);
}
// dispose temporary objects...
objGraphics.Dispose();
tmpBitmap.Dispose();
return (new Bitmap(bcodeWidth, bcodeHeight, PixelFormat.Format32bppArgb));
}
#endregion
#region Auxiliary Methods
private int Max(int v1, int v2)
{
return (v1 > v2 ? v1 : v2);
}
private int XCentered(int localWidth, int globalWidth)
{
return ((globalWidth - localWidth) / 2);
}
#endregion
}
Default.aspx code
<%# Page Title="Home Page" Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true"
CodeFile="Default.aspx.cs" Inherits="_Default" %>
<asp:Content ID="HeaderContent" runat="server" ContentPlaceHolderID="HeadContent">
</asp:Content>
<asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">
<h2>
Welcome to ASP.NET!
</h2>
<p>
To learn more about ASP.NET visit www.asp.net.
</p>
<p>
You can also find <a href="http://go.microsoft.com/fwlink/?LinkID=152368&clcid=0x409"
title="MSDN ASP.NET Docs">documentation on ASP.NET at MSDN</a>.
</p>
<asp:Image ID="imgBar" runat="server" />
</asp:Content>
I have created html code and then save this html page as an image . The html controls which I have created is showing properly in the image with all images and background color. It is woking fine on localhost.
but I am trying to creating html code to image on the server. the image is creating but it's not showing anything like bgcolor, images, etc.
only blank image is showing.
Code :
Using Ajax calling function from client side I am sending the html content to the serverside
Server Side Method
[System.Web.Services.WebMethod()]
public static void GenerateTemplateImage(string html_Content, string TemplateName)
{
var t = new Thread(MakeScreenshot);
t.SetApartmentState(ApartmentState.STA);
t.Start();
}
public static void MakeScreenshot()
{
Bitmap bitmap;
string html = string.Empty;
string Title = string.Empty;
string Meta = string.Empty;
string Style = string.Empty;
string ScriptBefore = string.Empty;
string ScriptAfter = string.Empty;
string Scripthead = string.Empty;
html="<div><div id='s_p_box-1' style='background-color: rgb(24, 0, 238); width: 109px; height: 75px;>Welcome </div>' <br/> <img id='template1' class='template' style='border:1px solid green; height:142px;width:116px' src='http://ace.demos.classicinformatics.com/Advertiser-Admin/Campaign/UserTemplate/template1.jpg'></div>";
WebBrowser wb = new WebBrowser();
wb.Navigate("about:blank");
if (wb.Document != null)
{
wb.Document.Write(html);
}
wb.DocumentText = html;
wb.ScrollBarsEnabled = false;
wb.ScriptErrorsSuppressed = true;
// Set the size of the WebBrowser control
// Take Screenshot of the web pages full width
// wb.Width = wb.Document.Body.ScrollRectangle.Width;
wb.Width = 1024;
// Take Screenshot of the web pages full height
// wb.Height = wb.Document.Body.ScrollRectangle.Height;
//wb.Height = 786;
wb.ScrollBarsEnabled = true;
if (wb.Height <= 0)
{
wb.Height = 1024;
}
//if (wb.Width <= 400)
//{
// wb.Width = 700;
//}
// Get a Bitmap representation of the webpage as it's rendered in the WebBrowser control
//Bitmap bitmap = new Bitmap(wb.Width, wb.Height);
//using (bitmap = new Bitmap(wb.Width, wb.Height))
using (bitmap = new Bitmap(wb.Width, wb.Height))
{
//wb.DrawToBitmap(bitmap, new Rectangle(0, 0, wb.Width, wb.Height));
wb.DrawToBitmap(bitmap, new Rectangle(0, 0, wb.Width, wb.Height));
//string imgPath = HttpContext.Current.Server.MapPath(System.Configuration.ConfigurationManager.AppSettings["ImgPath"].ToString());
//string imgPath="C:\\Projects\\aec\\Ace-A-Metric\\Advertiser-Admin\\Campaign\\UserTemplate\\";
string imgPath = URlPath + "test123" + ".bmp";
//bitmap.Save(#"D:\" + txtTempName.Text + ".bmp", System.Drawing.Imaging.ImageFormat.Bmp);
bitmap.Save(imgPath, System.Drawing.Imaging.ImageFormat.Bmp);
//string imgpath = Path.Combine(HttpContext.Current.Server.MapPath("~") + "Advertiser-Admin\\Campaign\\UserTemplate\\" + txtTempName.Text +".bmp");
//bitmap.Save(imgpath, System.Drawing.Imaging.ImageFormat.Bmp);
}
wb.Dispose();
GC.Collect();
}
Do not use the WebBrowser control, it is shipped with a lot of constraints due its COM legacy, and the very poor object model.
One of the possible solution is to use Awesomium.Net
Espacially, this article explain the process : Capturing Web-Pages With C# (.NET)
The major difference, is that Awesomium and its .Net wrapper is written with no dependency to the host (actually from the Chromium source code). Then the library is actually standalone and let you consider a lots of more scenarios.
I have a page that dynamically generates a small html page containing 1 small table w/text. I want to be able to take a picture (png preferable) of that page and save it to my server.
I was previously using a 3rd party solution (ABCdrawHTML2), but I have changed servers and this one does not have it. Is there a way to do it without 3rd party solutions?
This is how I do it using the Windows.Forms WebBrowser:
public class WebSiteThumbnailImage
{
string m_Url;
int m_BrowserWidth, m_BrowserHeight, m_ThumbnailWidth, m_ThumbnailHeight;
Bitmap m_Bitmap = null;
public WebSiteThumbnailImage(string url, int browserWidth, int browserHeight, int thumbnailWidth, int thumbnailHeight)
{
m_Url = url;
m_BrowserWidth = browserWidth;
m_BrowserHeight = browserHeight;
m_ThumbnailWidth = thumbnailWidth;
m_ThumbnailHeight = thumbnailHeight;
}
public Bitmap GenerateWebSiteThumbnailImage()
{
Thread m_thread = new Thread(new ThreadStart(_GenerateWebSiteThumbnailImage));
m_thread.SetApartmentState(ApartmentState.STA);
m_thread.Start();
m_thread.Join();
return m_Bitmap;
}
private void _GenerateWebSiteThumbnailImage()
{
WebBrowser m_WebBrowser = new WebBrowser();
m_WebBrowser.ScrollBarsEnabled = false;
m_WebBrowser.Navigate(m_Url);
m_WebBrowser.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(WebBrowser_DocumentCompleted);
while (m_WebBrowser.ReadyState != WebBrowserReadyState.Complete)
Application.DoEvents();
m_WebBrowser.Dispose();
}
private void WebBrowser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
WebBrowser m_WebBrowser = (WebBrowser)sender;
m_WebBrowser.ClientSize = new Size(this.m_BrowserWidth, this.m_BrowserHeight);
m_WebBrowser.ScrollBarsEnabled = false;
m_Bitmap = new Bitmap(m_WebBrowser.Bounds.Width, m_WebBrowser.Bounds.Height);
m_WebBrowser.BringToFront();
m_WebBrowser.DrawToBitmap(m_Bitmap, m_WebBrowser.Bounds);
m_Bitmap = (Bitmap)m_Bitmap.GetThumbnailImage(m_ThumbnailWidth, m_ThumbnailHeight, null, IntPtr.Zero);
}
}
To use this, at the appropriate place in your code-behind, do something like:
WebSiteThumbnailImage thumbnail = new WebSiteThumbnailImage(url, 1000, 1000, 200, 200);
Bitmap image = thumbnail.GenerateWebSiteThumbnailImage();
image.Save(filePath);
I have two functions:
Function 1: ImageToByteArray: Is used to Convert an Image into a Byte Array and then Store in an Oracle Database, in a BLOB Field.
public byte[] ImageToByteArray(string sPath)
{
byte[] data = null;
FileInfo fInfo = new FileInfo(sPath);
long numBytes = fInfo.Length;
FileStream fStream = new FileStream(sPath, FileMode.Open, FileAccess.Read);
BinaryReader br = new BinaryReader(fStream);
data = br.ReadBytes((int)numBytes);
return data;
}
Function 2: ByteArrayToImage: Is used to Convert a Byte Array from the Database into an Image:
public System.Drawing.Image ByteArrayToImage(byte[] byteArray)
{
MemoryStream img = new MemoryStream(byteArray);
System.Drawing.Image returnImage = System.Drawing.Image.FromStream(img);
return returnImage;
}
In my Markup I have an Imgage Control:
<asp:Image ID="Image1" runat="server" />
In the Code Behind I want to Assign the Returned Value from Function 2 to (which is of type System.Drawing.Image) to the "image1" control which is of type (System.Web.UI.WebControls.Image).
Obviously I can't just assign:
image1 = ByteArrayToImage(byteArray);
because I'd get the following error: Cannot implicitly convert type 'System.Drawing.Image' to 'System.Web.UI.WebControls.Image'
Is there anyway to do this?
It looks like you just want a simple method to convert an image byte array into a picture. No problem. I found an article that helped me a lot.
System.Web.UI.WebControls.Image image = (System.Web.UI.WebControls.Image)e.Item.FindControl("image");
if (!String.IsNullOrEmpty(currentAd.PictureFileName))
{
image.ImageUrl = GetImage(currentAd.PictureFileContents);
}
else
{
image.Visible = false;
}
//The actual converting function
public string GetImage(object img)
{
return "data:image/jpg;base64," + Convert.ToBase64String((byte[])img);
}
PictureFileContents is a Byte[] and that's what the function GetImage is taking as an object.
You can't. WebControls.Image is just a HTML container for an image url - you can't store the image data directly in it, you just store the reference (url) to an image file.
If you need to retrieve image data dynamically, the usual approach is to create an image handler that will handle the request and return the image as a stream that the browser can display.
See this question
I think it is possible and I hope it be helpful. My solution for this is here:
public System.Web.UI.WebControls.Image HexStringToWebControlImage(string hexString)
{
var imageAsString = HexString2Bytes(hexString);
MemoryStream ms = new MemoryStream();
ms.Write(imageAsString, 0, imageAsString.Length);
if (imageAsString.Length > 0)
{
var base64Data = Convert.ToBase64String(ms.ToArray());
return new System.Web.UI.WebControls.Image
{
ImageUrl = "data:image/jpg;base64," + base64Data
};
}
else
{
return null;
}
}
public byte[] HexString2Bytes(string hexString)
{
int bytesCount = (hexString.Length) / 2;
byte[] bytes = new byte[bytesCount];
for (int x = 0; x < bytesCount; ++x)
{
bytes[x] = Convert.ToByte(hexString.Substring(x * 2, 2), 16);
}
return bytes;
}
Ok i have been working non stop on this and doing a lot of searching. I cannot get my images to display when pulling them from the database. If i try going to the handler link manually i get a message saying "The image [Image] cannot be displayed because it contains errors". I had some old images in the database from before and it first displayed those correctly. But now if i update images it will give me this error when trying to view them.
Upload code.
if (fileuploadImage.HasFile)
{
if (IsValidImage(fileuploadImage))
{
int length = fileuploadImage.PostedFile.ContentLength;
byte[] imgbyte = new byte[length];
HttpPostedFile img = fileuploadImage.PostedFile;
img.InputStream.Read(imgbyte, 0, length);
if (mainImage == null)
{
ProfileImage image = new ProfileImage();
image.ImageName = txtImageName.Text;
image.ImageData = imgbyte;
image.ImageType = img.ContentType;
image.MainImage = true;
image.PersonID = personID;
if (image.CreateImage() <= 0)
{
SetError("There was an error uploading this image.");
}
}
else
{
mainImage.ImageName = txtImageName.Text;
mainImage.ImageType = img.ContentType;
mainImage.ImageData = imgbyte;
mainImage.MainImage = true;
mainImage.PersonID = personID;
if (!mainImage.UpdateImage())
{
SetError("There was an error uploading this image.");
}
}
}
else
{
SetError("Not a valid image type.");
}
Here is my image handler:
public class ImageHandler : IHttpHandler
{
public bool IsReusable
{
get
{
return false;
}
}
public void ProcessRequest(HttpContext context)
{
int imageid = Parser.GetInt(context.Request.QueryString["ImID"]);
ProfileImage image = new ProfileImage(Parser.GetInt(imageid));
context.Response.ContentType = image.ImageType;
context.Response.Clear();
context.Response.BinaryWrite(image.ImageData);
context.Response.End();
}
And this is how i'm calling it "~/ImageHandler.ashx?ImID=" + Parser.GetString(image.ImageID)
I'm using the data type Image in sql server to store this.
Edit:
I also found out that if i put a try catch around context.Response.end() it is erroring out saying the "Unable to evaluate the code because the native frame..."
I found my problem. I was checking the header of the actual file to make sure it was valid. Somehow that was altering the data and making it bad.