Cant Update Image in a quick succession - c#

I'm doing a simple code to update profile pics, by saving uploaded file into a folder and processing its required versions using Bitmap.
Issue is that i cant change image in quick succession, After changing once, it shows file is being used by another process. It works after logging out and logging in again.
fuPic.SaveAs(Server.MapPath("/assets/user_images_raw/" + Session["userid"].ToString() + ".jpg"));
flag = "yes";
Bitmap map = new Bitmap(System.Drawing.Image.FromFile(Server.MapPath("/assets/user_images_raw/" + Session["userid"].ToString() + ".jpg")), new Size(60, 60));
map.Save(Server.MapPath("/assets/user_images/" + Session["userid"].ToString() + ".jpg"), System.Drawing.Imaging.ImageFormat.Jpeg);
map.Dispose();
Bitmap map_2 = new Bitmap(System.Drawing.Image.FromFile(Server.MapPath("/assets/user_images_raw/" + Session["userid"].ToString() + ".jpg")), new Size(125, 125));
map_2.Save(Server.MapPath("/assets/user_thumbnails/" + Session["userid"].ToString() + ".jpg"), System.Drawing.Imaging.ImageFormat.Jpeg);
map_2.Dispose();
What am i missing ?
Edit: I'm not seeing any issue at localhost. Its just after hosting on IIS.

Related

IOException thrown from Image class or byte array

I'm extracting a ZIP file. This ZIP contains image files and an Excel file with a product list. When articles of different sizes are listed the article refers to the same image. I copy the image file to a local folder and write the (compressed) binary data to SQL server database.
So when it gets to the point where a JPG file shall be processed a second time, I get this exception, although I dispose the image object.
Worksheet ws;
string root = "C:\\images\\";
string file;
string importFolder = "C:\\import\\;
Dictionary <string, object> ins;
Image im;
Image th;
//Worksheet has been opened before
//ZIP has been extracted before to C:\import\
for (i = 2; i <= ws.Dimension.End.Row; i++) {
ins = new Dictionary<string, object>(); //Dictionary to write data to database
file = ws.Cells[i, 4].Text;
System.IO.File.Copy(importFolder + "\\" + file, root + "\\" + file, true); // <-- Here the exception is thrown in the second iteration
im = Image.FromFile(root + "\\" + file);
im = im.GetBetterThumbnail(1024);
byte[] im_data = im.GetJpgByteArray(85);
ins.Add("url", "www.test.de/images/" + file);
ins.Add("image_data", im_data);
ins.Add("image_size", im_data.Length);
//image will be written to database
im.Dispose();
im = null;
im_data = null;
//With these initializations there shouldn't be thrown an exception
} // end for
What am I missing? With resetting the Image object and byte array, there shouldn't be another reference to the image file.
I had a look on this
IOException: The process cannot access the file 'file path' because it is being used by another process
but I couldn't figure out, how to adept to my topic.
Yes, I could store all file names just to copy them once, but I think that's the lazy way.
Kind regards
You assign a value to the variable im two times.
One time you use im = Image.FromFile(root + "\\" + file) and the other time you use im = im.GetBetterThumbnail(1024). Could it be that this opens two handles that need to be closed?
Besides, it's better to use the using statement. Then you don't have to take care of the disposing by yourself.
For example like this:
for (i = 2; i <= ws.Dimension.End.Row; i++)
{
ins = new Dictionary<string, object>(); //Dictionary to write data to database
file = ws.Cells[i, 4].Text;
System.IO.File.Copy(importFolder + "\\" + file, root + "\\" + file, true);
using (im = Image.FromFile(root + "\\" + file))
{
// I guess that this method creates its own handle
// and therefore also needs to be disposed.
using (thumbnail = im.GetBetterThumbnail(1024))
{
byte[] im_data = thumbnail.GetJpgByteArray(85);
ins.Add("url", "www.test.de/images/" + file);
ins.Add("image_data", im_data);
ins.Add("image_size", im_data.Length);
//image will be written to database
}
}
} // end for
I got the issue solved by using a stream. The memory management works really better now.
New code:
//im = Image.FromFile(root + "\\" + file);
im = Image.FromStream(File.Open(root + "\\" + file, FileMode.Open));
So could it be that this is another 'Microsoft feature'?

Having issues setting up a simple filestream

I am writing an application that allows the user to import a picture from the computer and view it in my application. The user also has an import button under the picture and he/she can select the picture's destination in the computer.
My problem is that I get following exception:
System.IO.IOException: 'The process cannot access the file 'D:\Workspaces_Foo\Foo\Theme\MyPic.png' because it is being used by another process.'
when I debug it I find the line where it's breaking. It is in:
string image = Constants.ImageName;
if (image != "NONE")
{
using (var stream = File.OpenRead(SourceDir + ImageName))
{
Directory.CreateDirectory(Path.GetDirectoryName(DestinationDir + "\\" + image));
File.Copy(SourceDir + "\\" + image, DestinationDir + "\\" + image, true); //breaks here...
}
}
I assumed that by using a filestream it would've allowed me to continue with my picture transfer. Can anyone tell me why I am getting this error?
You are opening a stream for the file. This opens the file and marks it as in use.
Then you use File.Copy to copy it, but the Operating system says the file is in use (it isn't clever enough to notice that it is in use by your own process!)
Forget the stream, try this instead.
string image = Constants.ImageName;
if (image != "NONE")
{
Directory.CreateDirectory(Path.GetDirectoryName(DestinationDir + "\\" + image));
File.Copy(SourceDir + "\\" + image, DestinationDir + "\\" + image, true);
}

Ensure directory exists or create if needed before saving a file

I have a file name that I am generating from data that is coming from a database. I need to save the file to a folder location that is coming from a database query. How do I ensure the path exists so that when I save my file it will not throw an exception about a missing directory? My file saving code is listed below. When I call saveTemp.Save I am getting an exception because the directory does not exist.
Image<Bgr, Byte> newImage = sourceImage.WarpPerspective(mywarpmat, 355, 288, Emgu.CV.CvEnum.INTER.CV_INTER_LINEAR, Emgu.CV.CvEnum.WARP.CV_WARP_FILL_OUTLIERS, new Bgr(0, 0, 0));
Image<Bgr, Byte> savetemp = newImage.Copy();
savetemp.ROI = new Rectangle(lokasiX, lokasiY, templatewidth, templateheight);
savetemp.Save(#"D:\Dokumen\Alfon\TA Alfon\CobaFitur\Template\Kotak\" + simpantmp["namakamera"].ToString() + "Template_" + DateTime.Now.ToString("yyyyMMdd_hhmmss") + cnt + ".jpg");
You need to ensure the directory exists before you can save a file to it. You can do this using the Directory.CreateDirectory method. I would also modify your code to use the Path.Combine method to build your path.
var fileName = "Template_" + DateTime.Now.ToString("yyyyMMdd_hhmmss") + cnt + ".jpg");
var filePath = Path.Combine(#"D:\Dokumen\Alfon\TA Alfon\CobaFitur\Template\Kotak", simpantmp["namakamera"].ToString());
Directory.CreateDirectory(filePath);
saveTemp.Save(Path.Combine(filePath, fileName));

A generic error occurred in GDI+ (screenshot SaveAsFile, ExternalException)

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 ^^

Download of image from url

I've to download the images from particular URL using , for loop in case some products having more than 5 images .. when i click the product button some of the images only getting download not all images..but when i debug the corresponding code works fine, i.e, its downloads all the images..properly .
is this due to some cache .... or image file is in Gif format....
This is My Code
for (int i = 0; i < obj.Count; i++)
{
PartNAme = (obj[i].ToString().Split('='))[1];
_prtnm = PartNAme.ToString().Split(';')[0];
//this is url , source for the image
_final_URI = _URI + _Prod_name + '/' + _prtnm + ".GIF";
WebClient client = new WebClient();
string strtempname = DateTime.Now.ToString().Replace("/", "").Replace(":", "").Replace(" ", "");
rnd = new Random(100);
string _strfile = "PNImage" + strtempname + rnd.Next().ToString() + ".gif";
string _path = "../Images/PNImage/" + _strfile;
string _PPath = Server.MapPath(_path);
//to download image from source url, and path to save the image file
client.DownloadFile(_final_URI, _PPath);
}
in above code when i debug the image files are getting downloaded properly, but while running without debug some image files gets repeated so instead of getting original image file , old/same image file gets downloaded instead...
is this due to some cache .... or image file is in Gif format....
I think that random gives you the same number. See this thread for a fix Random number generator only generating one random number
If you debug you are way "slower" that without debugging. Another option would be to use guids as filename

Categories