I desperately need help with an issue I am having while trying load an image or unload an image using ASP/C#. The problem I am having is the first time I run the code and Load the image into the thumbnail, I have no problem but the minute I try to remove the picture or load a second or third image, it takes very very long to hit the event and I get an Out of Memory error. I think something is getting locked and takes a while to get unlocked but I am not sure.
Here is the code I am using:
protected void btnUploadImgPicture1_ServerClick(object sender, EventArgs e)
{
using (filePicture1)
{
if (filePicture1.PostedFile.FileName != "")
{
imageUtil = new ImageUtility();
string realPhysicalPath = Path.Combine(Server.MapPath("~/upload/"), filePicture1.PostedFile.FileName);
filePicture1.PostedFile.SaveAs(realPhysicalPath);
//imgVehiclePicture1.Src = realPhysicalPath;
using (imgVehiclePicture1)
{
imgVehiclePicture1.Attributes["src"] = imageUtil.getBase64String(realPhysicalPath);
Session.Add("Image1", realPhysicalPath);
imageUtil = null;
}
}
}
}
public string getBase64String(string path)
{
Image img = Image.FromFile(path);
byte[] imageBytes = imageToByteArray(img);
string base64String = Convert.ToBase64String(imageBytes, 0, imageBytes.Length);
return "data:image/png;base64," + base64String;
}
I am using this code on 3 times for 3 different events and then I am using similar code to remove the selected image from the upload.
What is ImageUtility? If it implements IDisposable then you might want to try explicitly disposing it instead of setting the variable to null. Even better if you can wrap it inside of a using block.
Related
I am trying to implement the jSignature library in my application but I can't make it work, the actual problem is trying to recreate the original image from the base30 text. In order to do it I draw something in their demo, take the base30 text and paste it in my app but the generated image has almost nothing to do with the original one. The code of my sample app is this:
private void BtnConvertToSVG_Click(object sender, EventArgs e)
{
convertFromBase30();
}
private void convertFromBase30()
{
try
{
jSignature.Tools.Base30Converter Base30 = new jSignature.Tools.Base30Converter();
String base30Text = tbBase30Text.Text.ToString();
int[][][] arrBase30 = Base30.Base30ToNative(base30Text);
String strSVG = jSignature.Tools.SVGConverter.ToSVG(arrBase30);
tbSVG.Text = strSVG;
MemoryStream s = new MemoryStream(Encoding.ASCII.GetBytes(strSVG));
SvgDocument mySVG = SvgDocument.Open<SvgDocument>(s, null);
var tempStream = new System.IO.MemoryStream();
mySVG.Draw().Save(tempStream, System.Drawing.Imaging.ImageFormat.Png);
System.Drawing.Image img = System.Drawing.Image.FromStream(tempStream);
pbImage.Image = img;
}
catch (Exception ex)
{
MessageBox.Show(String.Format("{0}", ex.Message));
}
}
It is a Windows Forms application with two TextBox:
tbBase30Text: Here I introduce the base30 text
tbSVG: Where the app writes the SVG image code
A Button (btnConvertToSVG) and a PictureBox where I print the generated image. It makes use of the libraries included in the jSignature project
If I draw an SO image in their demo it gives me the next result
Pasting the base30 code in my application gives me the next result:
I don't understand why but the only common thing between both signatures are the number of lines.
There are some forks of this library, the brinley's one (last updated) and the willowsystems's are which I tried with no success.
I finally solved it thanks to another SO question talking about the same problem. The error was in the library to convert to SVG included in the jSignature project.
All the String.Format ignore the Culture when converting the String adding errors to the final result, you can fix it by adding CultureInfo.InvariantCulture to all of them at the beginning
String.Format(CultureInfo.InvariantCulture, ...)
So I collect a varbinary(MAX) value from a database where an image is stored.
It gets converted to byte[], then the aim is to display this in an image control.
This is where I read from the database
public TemplateData(SqlDataReader dr)
{
initialiseData();
if (dr.HasRows)
{
Logo = (byte[])dr["Logo"];
//Logo = dr["Logo"].ToString();
TemplateId = dr["TemplateId"].ToString();
Comment = dr["Comment"].ToString();
SchemeCode = dr["SchemeCode"].ToString();
Version = dr["Version"].ToString();
}
}
This is where the values are displayed into the corresponding controls
protected void ddSchemeCode_SelectedIndexChanged(object sender, EventArgs e)
{
if (ddSchemeCode.SelectedIndex > 0)
{
// Existing Data to load from database
TemplateData temp = DataClass.ReturnData(ddSchemeCode.SelectedItem.Text);
if (temp != null)
{
txtVersion.Text = temp.Version;
txtComment.Text = temp.Comment;
txtSchemeCode.Text = temp.SchemeCode;
txtTemplateId.Text = temp.TemplateId;
img.Src = temp.Logo;
}
So at the moment I am passing a byte[] into the source of an image control, where it would instead like a string. I've tried converting it to a string with Convert.ToBase64String(Logo) and ToString(Logo) but these do not work.
Any help is greatly appreciated. Cheers guys and gals.
Try converting the byte array to image and assign it to picturebox as below,
try
{
using (MemoryStream mStream = new MemoryStream())
{
// where pData is your byte array
mStream.Write(pData, 0, Convert.ToInt32(pData.Length));
Image originalImage = Image.FromStream(mStream);
picBox.Image = originalImage;
}
}
catch (Exception ex)
{
}
Hope it helps.
As you may have noticed, you cannot "print" an image in a webpage. You need to get a little bit creative now.
What you want to look into is Response.BinaryWrite. More information about that, here: https://msdn.microsoft.com/en-us/library/system.web.httpresponse.binarywrite%28v=vs.110%29.aspx
You will probably also need a generic ashx handler. Here is an example of how to show a picture using a handler: http://www.dotnetperls.com/ashx
My suggestion would be to store the logo as a byte[] into the http session. Put the source of the image to theHttpHandlerYourGonnaCreate.ashx. You can then binary write the byte[] you've stored into the session there.
Hope this helps!
As Michael shows here, you can convert the byte array to a Bitmap object with something like this:
Bitmap bitmap = null;
using (MemoryStream imageStream = new MemoryStream(imageData))
{
bitmap = new Bitmap(imageStream);
}
It isn't entirely clear what you're using for a control to show the image, but any control that can display an image should be able to take a Bitmap or Image object.
Hello I tried looking through questions that may have my answer but none of them did.
I am doing web automation testing and trying to take a screenshot of when an error occurs and save it to a file in another folder.
My program has a 30 second timeout when searching for elements on the page. If after 30 seconds no element is found, it takes a SS, reloads the page, and tries again.
The first screenshot works fine. But on the second run through, it tries to save another screenshot to the folder and I get this incredibly vague error that is seemingly caused by a hundred different things, so I'm not quite sure what the problem is.
Here's my code:
public void takeScreenShot()
{
string ssPath = _persistencePath += "\\Errors";
string currTime = DateTime.Now.ToString(#"MMM-ddd-d-HH.mm");
Screenshot ss = ((ITakesScreenshot)_driver).GetScreenshot();
try
{
ss.SaveAsFile(ssPath + "\\ERROR-" + currTime + ".png", System.Drawing.Imaging.ImageFormat.Png);
ssCount = 0;
}
catch (System.Runtime.InteropServices.ExternalException)
{
ssCount++;
//error occurs here
ss.SaveAsFile(ssPath + "\\ERROR-" + currTime + "(" + ssCount + ")" + ".png", System.Drawing.Imaging.ImageFormat.Png);
}
I initially thought the issue was that it was trying to save a file of the same name, because if the error happens during the same minute then the file name is the same. So that's why I added that catch block, in an attempt to change the name if it occurs in the same minute. But that didn't fix it.
Again I tried searching all over and couldn't find an answer. Any help is greatly appreciated.
Well, if anyone's curious I solved it. Turns out I'm just an idiot.
string ssPath = _persistencePath += "\\Errors";
this line was appending another \Errors to the target path on the second run though. thus invalidating the path, because \Errors\Errors didn't exist.
Thanks to everyone who commented/tried to help!
The Screenshot class doesn't dispose of the image resource properly, so it may be a bug in the Selenium framework. A work-around is to do it yourself:
public void takeScreenShot()
{
string ssPath = System.IO.Path.Combine(_persistencePath, #"\Errors");
string currTime = DateTime.Now.ToString(#"MMM-ddd-d-HH.mm");
string fileName = System.IO.Path.Combine(ssPath, #"\ERROR-" + currTime + ".png");
Screenshot ss = ((ITakesScreenshot)_driver).GetScreenshot();
using (MemoryStream ms = new MemoryStream(ss.AsByteArray))
using (Image screenShotImage = Image.FromStream(ms))
{
Bitmap cp = new Bitmap(screenShotImage);
cp.Save(filename, ImageFormat.Png);
cp.Dispose();
}
}
No assurance that this will fix it, but at least you can be reasonable assured that the resources are disposed of properly.
Note requires you to reference System.Drawing.dll in the project.
Edit another workaround posted.
Finally i did it!
check out this, just write completed PATHNAME,
pathname+filename+extension: #"C:\folderWithPermission\test.bmp"
JUST TAKE FOLDER WITH WRITE PERMISSIONS, was like o.0
here's the method
public DriverExecutor CaptureScreen(string filename)
{
Screenshot shot = this.myRemoteWebDriver.GetScreenshot();
MemoryStream ms;
Image imgShot;
Bitmap bitmap;
try
{
using (ms = new MemoryStream(shot.AsByteArray))
using (imgShot = Image.FromStream(ms))
using (bitmap = new Bitmap(imgShot))
{
bitmap.Save(filename, ImageFormat.Bmp);
}
}catch(Exception err){}
return this;
}
NOTE: im asssuming what remoteDriver was rightly instanced and encapsulated on a own object , i hope this help you all ^^
Using DOTNET 3.5 . I have a app which shows load a flash movie in form, using this code
axShockwaveFlash1 = new AxShockwaveFlashObjects.AxShockwaveFlash()
axShockwaveFlash1.LoadMovie(0, Form1.currentGame);
The problem is that whenever I make a changes in the flash hosted in our application and try to refresh the to see the changes, the new changes is 'messed' up. to be more specific , it seems that the background and some controls of the previous flash still remain, 'spoiling' the new flash that is loaded. why?
Using the following methods before loading the second flash video makes no difference
axShockwaveFlash1.Refresh();
axShockwaveFlash1.Stop();
I tried other methods, it doesn't work for me. Here is what I did to achieve the desired result.
private void btnReload_Click(object sender, EventArgs e)
{
byte[] fileContent = File.ReadAllBytes(Application.StartupPath + #"\yourflashfile.swf");
if (fileContent != null && fileContent.Length > 0)
{
using (MemoryStream stm = new MemoryStream())
{
using (BinaryWriter writer = new BinaryWriter(stm))
{
/* Write length of stream for AxHost.State */
writer.Write(8 + fileContent.Length);
/* Write Flash magic 'fUfU' */
writer.Write(0x55665566);
/* Length of swf file */
writer.Write(fileContent.Length);
writer.Write(fileContent);
stm.Seek(0, SeekOrigin.Begin);
/* 1 == IPeristStreamInit */
//Same as LoadMovie()
this.axShockwaveFlash1.OcxState = new AxHost.State(stm, 1, false, null);
}
}
fileContent = null;
GC.Collect();
}
}
I copied the core code somewhere in SO but I don't remember the source.
Have you tried loading an "empty" flash video before loading your new video?
e.g.
axShockwaveFlash1.LoadMovie(0,"");
I'm sure that I encountered a similar problem and resolved it this way.
Try this.
Make a blank swf. "Blank.swf" load it first and then re-load your game.
axShockwaveFlash1.LoadMovie(0,"Blank.swf");
axShockwaveFlash1.Play();
axShockwaveFlash1.LoadMovie(0, Form1.currentGame);
axShockwaveFlash1.Play();
Ensure you give the correct path for the Blank.swf.
Here is my code to Serialize, Deserialize and Save an image to the file system. I have looked at many examples of serialization/deserialization and I just want to get some feedback as I am sure my code could be improved. Any feedback would be greatly appreciated. I know this is a common problem so hopefully this question will be a good resource for others in the future.
This is the revised code using recommendations:
private void Form1_Load(object sender, EventArgs e)
{
RunTest();
}
private void RunTest()
{
byte[] jpgba = ConvertFileToByteArray("D:\\Images\\Image01.jpg");
using (Image jpgimg = ConvertByteArrayToImage(jpgba))
{
SaveImageToFileSystem(jpgimg, "D:\\Images\\Image01_Copy.jpg");
}
byte[] pngba = ConvertFileToByteArray("D:\\Images\\Image02.png");
using (Image pngimg = ConvertByteArrayToImage(pngba))
{
SaveImageToFileSystem(pngimg, "D:\\Images\\Image02_Copy.png");
}
byte[] gifba = ConvertFileToByteArray("D:\\Images\\Image03.gif");
using (Image gifimg = ConvertByteArrayToImage(gifba))
{
SaveImageToFileSystem(gifimg, "D:\\Images\\Image03_Copy.gif");
}
MessageBox.Show("Test Complete");
this.Close();
}
private static byte[] ConvertFileToByteArray(String FilePath)
{
return File.ReadAllBytes(FilePath);
}
private static Image ConvertByteArrayToImage(byte[] ImageByteArray)
{
using (MemoryStream ms = new MemoryStream(ImageByteArray))
{
return Image.FromStream(ms);
}
}
private static void SaveImageToFileSystem(Image ImageObject, string FilePath)
{
// ImageObject.Save(FilePath, ImageObject.RawFormat);
// This method only works with .png files.
// This method works with .jpg, .png and .gif
// Need to copy image before saving.
using (Image img = new Bitmap(ImageObject.Width, ImageObject.Height))
{
using (Graphics tg = Graphics.FromImage(img))
{
tg.DrawImage(ImageObject, 0, 0);
}
img.Save(FilePath, img.RawFormat);
}
return;
}
What I have see from quick look:
Streams should be wrapped in using(...) pattern, in your case if exception occurs during processing, then Dispose() won't be called.
using (FileStream fs = new FileStream(FilePath, FileMode.Open))
{
// Another small optimization, removed unnecessary variable
byte[] iba = new byte[(int)fs.Length];
fs.Read(iba, 0, iba.Length);
}
You should catch only exceptions you expect. For example in SerializeImage this will be IOException. Catching all exceptions is very bad practice.
}
catch (IOException ex)
{
Image.FromStream method depends on stream, so if you close underlying stream and return Image you can receive unpredictable behavior (well, in most cases this will work, but sometimes error occurs). So you need to create image copy and return it.
using (MemoryStream ms = new MemoryStream(ImageByteArray))
{
using (Image img = Image.FromStream(ms))
{
return new Bitmap(img);
}
}
You are not disposed tg graphics object and img object in SaveImage method (but disposed ImageObject, see next paragraph). And in general I do not see necessity in such logic, simply call ImageObject.Save(..., ImageFormat.Png) if you want to save image preserving quality.
In the same method (SaveImage) you are disposed ImageObject parameter. This is also bad practice in most cases, consider disposing this image outside worker method by using using(...) pattern.
Here's a bit more:
private void RunTest()
{
// byte array that can be stored in DB
byte[] iba;
// image object to display in picturebox or used to save to file system.
iba = ReadImage("D:\\Images\\Image01.jpg");
using (Image img = DeserializeImage(iba))
{
SaveImage(img, "D:\\Images\\Image01_Copy.jpg");
}
iba = ReadImage("D:\\Images\\Image02.png");
using (Image img1 = DeserializeImage(iba))
{
SaveImage(img1, "D:\\Images\\Image02_Copy.png");
}
iba = ReadImage("D:\\Images\\Image03.gif");
using (var img2 = DeserializeImage(iba))
{
SaveImage(img2, "D:\\Images\\Image03_Copy.gif");
}
MessageBox.Show("Test Complete");
}
private static byte[] ReadImage(String filePath)
{
// This seems to be the easiest way to serialize an image file
// however it would be good to take a image object as an argument
// in this method.
using (var fs = new FileStream(filePath, FileMode.Open))
{
Int32 fslength = Convert.ToInt32(fs.Length);
var iba = new byte[fslength];
fs.Read(iba, 0, fslength);
return iba;
}
}
private static Image DeserializeImage(byte[] imageByteArray)
{
using (var ms = new MemoryStream(imageByteArray))
{
return Image.FromStream(ms);
}
}
private static void SaveImage(Image imageObject, string filePath)
{
// I could only get this method to work for .png files.
// imageObject.Save(filePath, imageObject.RawFormat);
// This method works with .jpg, .png and .gif
// Need to copy image before saving.
using (Image img = new Bitmap(imageObject.Width, imageObject.Height))
{
using (Graphics tg = Graphics.FromImage(img))
{
tg.DrawImage(imageObject, 0, 0);
}
img.Save(filePath, img.RawFormat);
}
return;
}
Note what you called Serializing is just reading the bytes in. Serializing is more what you're doing when you Save.
I got rid of all the try/catch blocks. The best they were doing for you is telling you whether the problem happened in Reading, Saving or Deserializing. You can determine that from the stack trace, which you were destroying by only displaying ex.Message.
You were also returning null on a serious exception, propagating failure.
Beside that I agree with everything arbiter said.
As John Saunder says, serializing and deserializing are more than just reading the raw data from a file. See Wiki on Serialization
For images in .net, you don't need to use anything more than the provided framework methods (most of the time)
So Loading an Image (De-Serialization) in .net is.
using System.Drawing.Image;
Image test;
test = Image.FromFile(#"C:\myfile.jpg")
test = Image.FromStream(myStream); // or you can load from an existing stream
Likewise, Saving the image (Serialization) is:
test.Save(#"C:\anotherFile.jpg", System.Drawing.Imaging.ImageFormat.Jpeg);
These are the basics of loading and saving an image in .net. If you have a more specific scenario, ask another question.