How to prevent an exception when canceling an OpenFileDialog? - c#

I click on the button to upload a photo. When I cancel the photo selection, the program throws an exception.
Here's my code:
private void button1_Click(object sender, EventArgs e)
{
Image<Bgr, byte> img = new Image<Bgr, byte>(Islem.getFileName());
ımageBox1.Image = img;
}
class Islem
{
public static string getFileName()
{
OpenFileDialog ofd = new OpenFileDialog();
ofd.Filter = "Images (*.BMP;*.JPG;*.GIF)|*.BMP;*.JPG;*.GIF|" + "All files (*.*)|*.*";
if (ofd.ShowDialog() == DialogResult.OK)
{
return ofd.FileName;
}
return "";
}
}
How to fix this situation?

When the user cancels the dialog, your getFileName function returns an empty string. Therefore, you get an exception when you try to load the image from a path that doesn't exist (i.e., the empty string). If you read the exception message, you would figure it out yourself.
You can do something like this:
private void button1_Click(object sender, EventArgs e)
{
string imgFilePath = Islem.getFileName();
if (!string.IsNullOrEmpty(imgFilePath))
{
Image<Bgr, byte> img = new Image<Bgr, byte>(imgFilePath);
ımageBox1.Image = img;
}
}
That would only use the file path (i.e., load the image) if the returned string isn't empty.
Alternatively, you can check if the file exists:
if (System.IO.File.Exists(imgFilePath)) { //use it to load the image }

Related

Cant copy a png image in c#

I am creating an app that i need to copy some png files.
I already have searching with many keywords, finding many solutions and none of them worked, so i decided to ask here.
There is the code,it uses a windows forms and "this" refers to this window
private void button2_Click(object sender, EventArgs e)
{
//yes i commented them to solve why the file was not copying
//try
{
FileInfo x = new FileInfo(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + #"\some_location");
x.CopyTo(textBox1.Text);
}
//catch
{ }
this.Close();
}
private void button1_Click(object sender, EventArgs e)
{
OpenFileDialog openDialog = new OpenFileDialog();
openDialog.Title = "Select Image To Load";
openDialog.Filter = "Text Files (*.png)|*.png" + "|" + "All Files (*.*)|*.*";
if (openDialog.ShowDialog() == DialogResult.OK)
{
string PathData = openDialog.FileName;
textBox1.Text = PathData;
}
}
I have gotten several different errors, but most common there is:
System.UnauthorizedAccessException
It looks a bit weird to me that you're using an OpenFileDialog to select a destination. I'd assume you'd want to either do it the other way around:
private void button2_Click(object sender, EventArgs e)
{
//yes i commented them to solve why the file was not copying
//try
{
FileInfo x = new FileInfo(textBox1.Text);
x.CopyTo(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + #"\some_location");
}
//catch
{ }
this.Close();
}
private void button1_Click(object sender, EventArgs e)
{
OpenFileDialog openDialog = new OpenFileDialog();
openDialog.Title = "Select Image To Load";
openDialog.Filter = "Text Files (*.png)|*.png" + "|" + "All Files (*.*)|*.*";
if (openDialog.ShowDialog() == DialogResult.OK)
{
string PathData = openDialog.FileName;
textBox1.Text = PathData;
}
}
or use SaveFileDialog instead.

How to clear a pictureBox in C#? I have tried setting the property to null but it doesnt work

I would like to clear a pictureBox after clicking on an 'Encode' button to save it as a new image file in my project. I would like to clear the fields on the form after the user saves the image file.
The code I use to display image on pictureBox:
private void btnOpenfile_Click(object sender, EventArgs e)
{
// open file dialog
OpenFileDialog open = new OpenFileDialog();
// image filters
open.Filter = "Image Files (*.png)|*.png";
if (open.ShowDialog() == DialogResult.OK)
{
// display image in picture box
pictureBox1.Image = new Bitmap(open.FileName);
pictureBox1.SizeMode = PictureBoxSizeMode.Zoom;
tbFilepath.Text = open.FileName;
//pictureBox1.ImageLocation = tbFilepath.Text;
}
}
The code I used to clear the pictureBox:
private void clearForm()
{
pictureBox1.Image = null; //doesn't work
pictureBox1.Invalidate(); //doesn't work
tbFilepath.Text = "";
tbMessage.Text = "";
}
I have also tried the following but it did not work either:
private void clearForm()
{
Bitmap bm = new Bitmap(img);
bm.Save(tbFilepath.Text,System.Drawing.Imaging.ImageFormat.Png);
}
I tried using the Refresh() method as one of the commentors suggested, but it did not work either:
private void clearForm()
{
Refresh(); //first attempt
pictureBox1.Refresh();// second attempt
}
I expect the pictureBox field to clear out the existing image I have selected but the image did not clear away.
Before clicking on encode button
After clicking on encode button, the textBox fields are cleared but not the pictureBox field. I used the codes I have added in this question.
Try creating a new Bitmap Variable and use it for the picturebox:
Bitmap bitmap = new Bitmap(pictureBox.Width, pictureBox.Height);
pictureBox.Image = bitmap;
pictrueBox.Invalidate();
Also, try to declare a Global Variable for the Bitmap so it is the one to be set as the picture and also the one to be cleared before setting it as the image for the PictureBox.
On the other hand you could try using the OnPaint Method of the Picurebox:
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
bm = new Bitmap(pictureBox1.Width, pictureBox1.Height);
}
Bitmap bm = null;
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
pictureBox1.Image = bm;
}
private void btn_Open_Click(object sender, EventArgs e)
{
OpenFileDialog ofd = new OpenFileDialog();
ofd.Filter = "Image Files(*.jpg; *.jpeg; *.gif; *.bmp); *.PNG|*.jpg; *.jpeg; *.gif; *.bmp; *.PNG";
if (ofd.ShowDialog() == DialogResult.OK)
{
bm = new Bitmap(Image.FromFile(ofd.FileName), new Size(pictureBox1.Width, pictureBox1.Height));
textBox1.Text = ofd.FileName;
pictureBox1.Invalidate();
}
}
private void btn_Clear_Click(object sender, EventArgs e)
{
bm = null;
pictureBox1.Invalidate();
}
These code I made worked perfectly. So please try it.

Converting image with OpenfileDialog

I need help with this code. I want to create basic image convert program but this program is not working? What am I doing wrong. Thanks for answers.
private void button1_Click(object sender, EventArgs e)
{
OpenFileDialog file = new OpenFileDialog();
file.ShowDialog();
string DosyaYolu = file.FileName;
string DosyaAdi = file.SafeFileName;
if (file.ShowDialog() == DialogResult.OK)
{
System.Drawing.Image image = System.Drawing.Image.FromFile(DosyaYolu);
image.Save(DosyaYolu, System.Drawing.Imaging.ImageFormat.Png);
}
You choose the wrong target path to save the new image to. Also you invoked the ShowDialog() twice, which is not necessary. The following code will save the new file with the same name but a different extension.
var dialog = new OpenFileDialog();
if (dialog.ShowDialog() == DialogResult.OK)
{
string sourceFile = dialog.FileName;
string targetFile = Path.ChangeExtension(sourceFile, "png");
Image image = Image.FromFile(sourceFile);
image.Save(targetFile, ImageFormat.Png);
}

How do i read already opened file in a another button click event directly .(i.e without open file dialogue in button click)

void OpenWithDialog()
{
var ofd = new OpenFileDialog();
ofd.Filter = "Triangle polygon file|*.poly";
if (ofd.ShowDialog() == DialogResult.OK)
{
OpenPolyFile(ofd.FileName);
}
}
void OpenPolyFile(string file)
{
var geometry = TriangleNet.IO.FileReader.ReadPolyFile(file);
// ...
}
private void button1_Click(object sender, EventArgs e)
{
}
How to read files in button1 click directly?
what you want is that your geometry object be accessible in additional scopes besides OpenPolyFile(). So you can simply make the geometry declaration accessible to both methods, declaring it, say, in the form code behind
// class scoped variables
[ThePolyFileType] (pick the right one here :) geometry = null;
void OpenWithDialog()
{
var ofd = new OpenFileDialog();
ofd.Filter = "Triangle polygon file|*.poly";
if (ofd.ShowDialog() == DialogResult.OK)
{
OpenPolyFile(ofd.FileName);
}
}
void OpenPolyFile(string file)
{
geometry = TriangleNet.IO.FileReader.ReadPolyFile(file);
// ...
}
private void button1_Click(object sender, EventArgs e)
{
if (geometry != null)
{
//do your stuff
}
}
How do i read already opened file in a another button click event
directly .(i.e without open file dialogue in button click)
I'm not quite sure why you want to read it twice, but if that requirement says, make selected filename available globally and use it.
private string filename;
void OpenWithDialog()
{
var ofd = new OpenFileDialog();
ofd.Filter = "Triangle polygon file|*.poly";
if (ofd.ShowDialog() == DialogResult.OK)
{
OpenPolyFile(ofd.FileName);
filename = ofd.FileName
}
}
Now you have opened filename available in button_clcik you can use this file and read again.
private void button1_Click(object sender, EventArgs e)
{
// now you can read the file.
//File.ReadAllText(filename); //OR
TriangleNet.IO.FileReader.ReadPolyFile(file);
}

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

Categories