OpenFile Dialog Box keeps resources open - c#

After opening a photo in my application using the Openfile Dialog I cannot do anything with the file unless I close my application. I have placed the OpenFile Dialog in a using statement and tried various ways to release resources with no success. How can I release the process to avoid the error message "The process cannot access the file because it is being used by another process?
using (OpenFileDialog GetPhoto = new OpenFileDialog())
{
GetPhoto.Filter = "images | *.jpg";
if (GetPhoto.ShowDialog() == DialogResult.OK)
{
pbPhoto.Image = Image.FromFile(GetPhoto.FileName);
txtPath.Text = GetPhoto.FileName;
txtTitle.Text = System.IO.Path.GetFileNameWithoutExtension(GetPhoto.Fi‌​leName);
//GetPhoto.Dispose(); Tried this
//GetPhoto.Reset(); Tried this
//GC.Collect(): Tried this
}
}

Your problem is not (OpenFileDialog) your problem is for PictureBox
you can use this for load image or if this not works
do this for load image
OpenFileDialog GetPhoto = new OpenFileDialog();
GetPhoto.Filter = "images | *.jpg";
if (GetPhoto.ShowDialog() == DialogResult.OK)
{
FileStream fs = new FileStream(path: GetPhoto.FileName,mode: FileMode.Open);
Bitmap bitmap = new Bitmap(fs);
fs.Close(); // End using
fs.Dispose();
pbPhoto.Image = bitmap;
txtPath.Text = GetPhoto.FileName;
txtTitle.Text = System.IO.Path.GetFileNameWithoutExtension(GetPhoto.Fi‌​leName);
}

As stated in the doc for Image.FromFile:
The file remains locked until the Image is disposed.
So you could try to make a copy of the image and then release an original Image:
using (OpenFileDialog GetPhoto = new OpenFileDialog())
{
GetPhoto.Filter = "images | *.jpg";
if (GetPhoto.ShowDialog() == DialogResult.OK)
{
using (var image = Image.FromFile(GetPhoto.FileName))
{
pbPhoto.Image = (Image) image.Clone(); // Make a copy
txtPath.Text = GetPhoto.FileName;
txtTitle.Text = System.IO.Path.GetFileNameWithoutExtension(GetPhoto.Fi‌​leName);
}
}
}
If it not help, you could try to make a copy via the MemoryStream and the Image.FromStream method: System.Drawing.Image to stream C#

Related

How to allow user to change download path?

I'm working on a Winform project,
I have a panel(PNLdownload) the user can download by pressing a button, here's the code:
Bitmap bmp = new Bitmap(PNLdownload.Width, PNLdownload.Height + 120);
PNLdownload.DrawToBitmap(bmp, PNLdownload.Bounds);
bmp.Save(#"C:\Test\Test.bmp");
I want the user to be able to choose where to download the image, how can I do this?
I couldn't find a way to do this on the web
You can use a SaveFileDialog.
Adapting the sample code at the provided link yields:
Stream myStream;
SaveFileDialog saveFileDialog1 = new SaveFileDialog();
Bitmap bmp = new Bitmap(PNLdownload.Width, PNLdownload.Height + 120);
PNLdownload.DrawToBitmap(bmp, PNLdownload.Bounds);
saveFileDialog1.Filter = "*.bmp";
saveFileDialog1.RestoreDirectory = true;
if(saveFileDialog1.ShowDialog() == DialogResult.OK)
{
if((myStream = saveFileDialog1.OpenFile()) != null)
{
bmp.Save(myStream, ImageFormat.Bmp);
myStream.Close();
}
}

C# Create txt file and save

I am trying to create a file and save text, but it's only creating file can anyone suggest what the problem is?
private void button2_Click(object sender, EventArgs e)
{
SaveFileDialog sfd = new SaveFileDialog();
sfd.Filter = "Text File|*.txt";
sfd.FileName = "Password";
sfd.Title = "Save Text File";
if (sfd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
string path = sfd.FileName;
StreamWriter bw = new StreamWriter(File.Create(path));
bw.Write(randomstring);
bw.Dispose();
}
}
You need to call bw.Close() before calling bw.Dispose(). Per the API: "You must call Close to ensure that all data is correctly written out to the underlying stream." (http://msdn.microsoft.com/en-us/library/system.io.streamwriter.close(v=vs.110).aspx)
I'd actually change the code to:
using (StreamWriter bw = new StreamWriter(File.Create(path)))
{
bw.Write(randomstring);
bw.Close();
}
The using block will automatically call Dispose(), whether or not everything completes successfully.
Try and use File.WriteAllText instead
if (sfd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
//...
File.WriteAllText(path, randomstring);
}
bw.Write(randomstring);
bw.Dispose();
You write something, then dispose of the object entirely. Try:
bw.Write(randomstring);
bw.Close();
bw.Dispose();
Per the documentation, you need to call bw.Close() before you dispose of it. Also, you should use using to ensure that all IDisposables are properly disposed of.
if (sfd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
string path = sfd.FileName;
using (var fs = File.Create(path))
using (StreamWriter bw = new StreamWriter(fs))
{
bw.Write(randomstring);
bw.Close();
}
}
Or just use File.WriteAllText:
if (sfd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
string path = sfd.FileName;
File.WriteAllText(path, randomstring);
}

Deleting File which is displayed in picturebox

I am selecting file from openfiledialoge and displaying it in picturebox and its name in textbox when I click on delete button I am getting exception The process cannot access the file because it is being used by another process.
I searched a lot for this exception to get resolved but i didn't fine any of them working, when i tried closing file with imagename which is in textbox i.e the file i am displaying in picturebox ; using IsFileLocked method,this closes and deletes all files of particular directory path ,but how can I delete the only file shown in picturebox,where I am going wrong
public partial class RemoveAds : Form
{
OpenFileDialog ofd = null;
string path = #"C:\Users\Monika\Documents\Visual Studio 2010\Projects\OnlineExam\OnlineExam\Image\"; // this is the path that you are checking.
public RemoveAds()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
if (System.IO.Directory.Exists(path))
{
ofd = new OpenFileDialog();
ofd.InitialDirectory = path;
DialogResult dr = new DialogResult();
if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
Image img = new Bitmap(ofd.FileName);
string imgName = ofd.SafeFileName;
txtImageName.Text = imgName;
pictureBox1.Image = img.GetThumbnailImage(350, 350, null, new IntPtr());
ofd.RestoreDirectory = true;
}
}
else
{
return;
}
}
private void button2_Click(object sender, EventArgs e)
{
//Image img = new Bitmap(ofd.FileName);
string imgName = ofd.SafeFileName;
if (Directory.Exists(path))
{
var directory = new DirectoryInfo(path);
foreach (FileInfo file in directory.GetFiles())
{ if(!IsFileLocked(file))
file.Delete();
}
}
}
public static Boolean IsFileLocked(FileInfo path)
{
FileStream stream = null;
try
{ //Don't change FileAccess to ReadWrite,
//because if a file is in readOnly, it fails.
stream = path.Open ( FileMode.Open, FileAccess.Read, FileShare.None );
}
catch (IOException)
{ //the file is unavailable because it is:
//still being written to or being processed by another thread
//or does not exist (has already been processed)
return true;
}
finally
{
if (stream != null)
stream.Close();
}
//file is not locked
return false;
}
}
Thanks in advance for any help
The (previously) accepted answer to this question is very poor practice. If you read the documentation on System.Drawing.Bitmap, in particular for the overload that creates a bitmap from a file, you will find :
The file remains locked until the Bitmap is disposed.
in your code you create the bitmap and store it in a local variable but you never dispose of it when you are done. This means your image object has gone out of scope but has not released its lock on the image file you are trying to delete. For all objects that implement IDisposable (like Bitmap) you must dispose of them yourself. See this question for example (or search for others - this is a very important concept!).
To correct the problem properly you simply need to dispose of the image when you are done with it :
if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
Image img = new Bitmap(ofd.FileName); // create the bitmap
string imgName = ofd.SafeFileName;
txtImageName.Text = imgName;
pictureBox1.Image = img.GetThumbnailImage(350, 350, null, new IntPtr());
ofd.RestoreDirectory = true;
img.Dispose(); // dispose the bitmap object
}
Please do not take the advice in the answer below - you should nearly never need to call GC.Collect and if you need to do it to make things work it should be a very strong signal that you are doing something else wrong.
Also, if you only want to delete the one file (the bitmap you have displayed) your deletion code is wrong and will delete every file in the directory as well (this is just repeating Adel's point). Further, rather than keep a global OpenFileDialog object alive simply to store the file name, I would suggest getting rid of that and saving just the file info :
FileInfo imageFileinfo; //add this
//OpenFileDialog ofd = null; Get rid of this
private void button1_Click(object sender, EventArgs e)
{
if (System.IO.Directory.Exists(path))
{
OpenFileDialog ofd = new OpenFileDialog(); //make ofd local
ofd.InitialDirectory = path;
DialogResult dr = new DialogResult();
if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
Image img = new Bitmap(ofd.FileName);
imageFileinfo = new FileInfo(ofd.FileName); // save the file name
string imgName = ofd.SafeFileName;
txtImageName.Text = imgName;
pictureBox1.Image = img.GetThumbnailImage(350, 350, null, new IntPtr());
ofd.RestoreDirectory = true;
img.Dispose();
}
ofd.Dispose(); //don't forget to dispose it!
}
else
{
return;
}
}
Then in your second button handler you can just delete the one file you are interested in.
private void button2_Click(object sender, EventArgs e)
{
if (!IsFileLocked(imageFileinfo))
{
imageFileinfo.Delete();
}
}
I had the same problem : I loaded a file in a PictureBox and when trying to delete it I got the same exception.
This occurred only when the image was displayed.
I tried them all :
picSelectedPicture.Image.Dispose();
picSelectedPicture.Image = null;
picSelectedPicture.ImageLocation = null;
and still got the same exception.
Then I found this on CodeProject : [c#] delete image which is opened in picturebox.
Instead of using PictureBox.Load() it creates an Image from the file and sets it as PictureBox.Image:
...
// Create image from file and display it in the PictureBox
Image image = GetCopyImage(imagePath);
picSelectedPicture.Image = image;
...
private Image GetCopyImage(string path) {
using (Image image = Image.FromFile(path)) {
Bitmap bitmap = new Bitmap(image);
return bitmap;
}
}
No more exceptions when I delete the file.
IMHO, this is the most suitable solution.
EDIT
I forgot to mention that you can safely delete the file immediately after display :
...
// Create image from file and display it in the PictureBox
Image image = GetCopyImage(imagePath);
picSelectedPicture.Image = image;
System.IO.File.Delete(imagePath);
...
use this code
string imgName = ofd.SafeFileName;
if (Directory.Exists(path))
{
var directory = new DirectoryInfo(path);
foreach (FileInfo file in directory.GetFiles())
{
GC.Collect();
GC.WaitForPendingFinalizers();
file.Delete();
}
}
Your button2_Click event handler is cycling through all the files inside your directory & doing the deletes.
You need to change your code like the following:
public partial class RemoveAds : Form
{
OpenFileDialog ofd = null;
string path = #"C:\Users\Monika\Documents\Visual Studio 2010\Projects\OnlineExam\OnlineExam\Image\"; // this is the path that you are checking.
string fullFilePath;
public RemoveAds()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
if (System.IO.Directory.Exists(path))
{
ofd = new OpenFileDialog();
ofd.InitialDirectory = path;
DialogResult dr = new DialogResult();
if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
Image img = new Bitmap(ofd.FileName);
string imgName = ofd.SafeFileName;
txtImageName.Text = imgName;
pictureBox1.Image = img.GetThumbnailImage(350, 350, null, new IntPtr());
fullFilePath = ofd.FilePath;
ofd.RestoreDirectory = true;
}
}
else
{
return;
}
}
private void button2_Click(object sender, EventArgs e)
{
FileInfo file = new FileInfo(fullFilePath);
if(!IsFileLocked(file))
file.Delete();
}
}
public static Boolean IsFileLocked(FileInfo path)
{
FileStream stream = null;
try
{ //Don't change FileAccess to ReadWrite,
//because if a file is in readOnly, it fails.
stream = path.Open ( FileMode.Open, FileAccess.Read, FileShare.None );
}
catch (IOException)
{ //the file is unavailable because it is:
//still being written to or being processed by another thread
//or does not exist (has already been processed)
return true;
}
finally
{
if (stream != null)
stream.Close();
}
//file is not locked
return false;
}
}
By using GetThumnailImage you have to specify the width and height which is static.
Use the Load method instead.
eg: pictureBox1.Load(Path to the image); by using this u will have no problem in deleting the image or the folder before closing the app. no other methods need to be created.
hope this helps

uploading images in winforms application

Does anyone know if a there is a control to allow the user to upload a image to a windows form? Or any example code to accomplish this.
I am using win-form applications
Thanks,
To allow users to select files in a Windows Forms application you should look into using the OpenFileDialog class.
To use the dialog on your form you will need to find it in the toolbox in Visual Studio and drag it on to your form.
Once associated with the form you can then invoke the dialog from your code like so:
if (openFileDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
string selectedFile = openFileDialog1.FileName;
}
You can then use the file path to perform whatever task you wish with the file.
Note: You can use the FileDialog.Filter Property to limit the type of file extensions (images in your case) the user can select when using the dialog.
It's note clear where you are going to upload your image. If you just want to use an image in a simple desktop application you can use OpenFileDialog to allow a user to select an image file. And then you can use this image path in you application. If you you want to upload this image to database you can read this image into memory using something like FileStream class.
OpenFileDialog open = new OpenFileDialog();
open.Filter = "Image Files(*.jpeg;*.bmp;*.png;*.jpg)|*.jpeg;*.bmp;*.png;*.jpg";
if (open.ShowDialog() == DialogResult.OK)
{
textBox10.Text = open.FileName;
}
cn.Open();
string image = textBox10.Text;
Bitmap bmp = new Bitmap(image);
FileStream fs = new FileStream(image, FileMode.Open, FileAccess.Read);
byte[] bimage = new byte[fs.Length];
fs.Read(bimage, 0, Convert.ToInt32(fs.Length));
fs.Close();
SqlCommand cmd = new SqlCommand("insert into tbl_products(Product_image) values(#imgdata)", cn);
cmd.Parameters.AddWithValue("#imgdata", SqlDbType.Image).Value = bimage;
cmd.ExecuteNonQuery();
cn.Close();
private void cmdBrowser_Click(object sender, EventArgs e)
{
OpenFileDialog fileOpen = new OpenFileDialog();
fileOpen.Title = "Open Image file";
fileOpen.Filter = "JPG Files (*.jpg)| *.jpg";
if (fileOpen.ShowDialog() == DialogResult.OK)
{
picImage.Image = Image.FromFile(fileOpen.FileName);
}
fileOpen.Dispose();
}

How to display an image from file system in a PictureBox in WinForm

I have a small doubt regarding loading an image in PictureBox in WinForms.
I want to show an image file from file system in a PictureBox on my form, say form1.
I am doing Windows applications using C#.
I want to check the file type also say is it pdf/text/png/gif/jpeg.
Is it possible to programmatically open a file from file system using C#?
If anyone knows please give any idea or sample code for doing this.
Modified Code: I have done like this for opening a file in my system, but I don't know how to attach the file and attach the file.
private void button1_Click(object sender, EventArgs e)
{
string filepath = #"D:\";
openFileDialog1.Filter = "Image Files (*.jpg)|*.jpg|(*.png)|*.png|(*.gif)|*.gif|(*.jpeg)|*.jpeg|";
openFileDialog1.CheckFileExists = true;
openFileDialog1.CheckPathExists = true;
if (openFileDialog1.ShowDialog(this) == DialogResult.OK)
{
try
{
}
}
}
I don't know what I have to write in try block. Can anyone help on this?
Use Image.ImageFromFile http://msdn.microsoft.com/en-us/library/system.drawing.image.fromfile.aspx method
Image img = Image.ImageFromFile(openFileDialog1.FileName);
Should work.
EDIT
If you're going to set it to PictureBox, and what to see complete inside it, use picturebox
SizeMode property.
using System.IO;
openFileDialog1.FilterIndex = 1;
openFileDialog1.Multiselect = false; //not allow multiline selection at the file selection level
openFileDialog1.Title = "Open Data file"; //define the name of openfileDialog
openFileDialog1.InitialDirectory = #"Desktop"; //define the initial directory
if (openFileDialog1.ShowDialog(this) == DialogResult.OK)
{
try
{
string filename = openFileDialog1.FileName;
FileStream fs=new FileStream(filename, FileMode.Open, FileAccess.Read); //set file stream
Byte[] bindata=new byte[Convert.ToInt32(fs.Length)];
fs.Read(bindata, 0, Convert.ToInt32(fs.Length));
MemoryStream stream = new MemoryStream(bindata);//load picture
stream.Position = 0;
pictureBox1.Image = Image.FromStream(stream);
}
}

Categories