Check if several files exists in a directory - c#

I am saving a new image everytime the uploader cropped the image and I want to check every new image if it exists. I have this code:
private void pictureBox5_MouseUp(object sender, MouseEventArgs e)
{
Selecting = false;
// Copy the selected area.
SelectedArea = GetSelectedArea(pictureBox5.Image, Color.Transparent, Points);
SelectedArea.Save(#"C:\Users\User\Desktop\Gallery\image1cropped.png", ImageFormat.Png);
}
I want it to save like image2cropped, image3cropped.. and check if it exists like
if(File.Exists(#"C:\Users\User\Desktop\Gallery\image1cropped.png", ImageFormat.Png);
I want it to check like image2cropped, image3cropped.. and so on.
ideas?

If I understand : your are saving an area to a file. The first time, you save it to image1cropped.png, and then you want automaticaly use image2cropped in order to not overwrite the first file, right ?
In this case, you can use this code :
int i = 0; // set 0 to start at 1 for "image1cropped"
string freeFileName; // the final fileName that doesn't exist
// loop while file imageXcropped exists
do
{
i++;
freeFileName = #"C:\Users\User\Desktop\Gallery\image" + i + "cropped.png";
} while (File.Exists(freeFileName));
// at this point freeFileName doesn't exists, you can use it
// use : SelectedArea.Save(freeFileName, ImageFormat.Png);

Related

How to fix ListView.LargeImageList showing images twice

I am working on a piece of software, which compares memes and helps users organize memes on their computer. As a part of this I am using Windows.Forms to build a UI. This UI lets the user add folders to be checked for images, which can be compared to a set of known meme templates.
My issue arises when I try to show the user the found images. To do this I am using a ListView and the property LargeImageList to contain a tuple of the image and the name of the image file.
Here is the piece of code in question:
private void button1_Click(object sender, EventArgs e)
{
int i = 0;
var ic = new ImageCollection();
var fbd = new FolderBrowserDialog();
fbd.Description = "Select meme folder or image.";
if (fbd.ShowDialog() == DialogResult.OK)
{
string[] files = Directory.GetFiles(fbd.SelectedPath);
foreach (var file in files)
{
if (!ic.CheckIfImage(file)) continue;
imageList1.Images.Add(Image.FromFile(file));
}
foreach (var file in files)
{
listView1.Items.Add($"{Path.GetFileNameWithoutExtension(file)}", i++);
}
}
}
This is an example of what the user sees when they first load in a folder. When the user tries to load in another folder this happens. It shows the images from the first folder, with the names of the image files from the second folder.
Does anyone know a fix for this issue? I have tried a variety of options in order to get around the issue. All from trying to clear the ImageList used to contain the images, to trying my hand at controlling when the ListView updates. None of this has worked. I have also tried googling the issue, but with no luck of finding a fix.
Thank you in advance.
If you want to show the content of a single folder at the time, then dispose of the objects in your ImageList.
If you instead want to show the content of more than one folder, you need to specify the new index of the image added. You're instead adding a new Item in the ListView using the same index reference:
int i = 0;
//(...)
listView1.Items.Add($"{Path.GetFileNameWithoutExtension(file)}", i++);
The indexer (i) always starts from 0, thus the ListView Item will use the images in your Imagelist starting from the Image at Index[0] each time. The new images won't ever be shown.
You can use the ImageList.Images.Count value, representing the number of Images already added to the ImageList, as base and increment the indexer starting from this value:
private void button1_Click(object sender, EventArgs e)
{
int i = imageList1.Images.Count;
var ic = new ImageCollection();
var fbd = new FolderBrowserDialog();
fbd.Description = "Select meme folder or image.";
if (fbd.ShowDialog() == DialogResult.OK)
{
foreach (var file in Directory.GetFiles(fbd.SelectedPath))
{
if (!ic.CheckIfImage(file)) continue;
imageList1.Images.Add(new Bitmap(file, true));
listView1.Items.Add($"{Path.GetFileNameWithoutExtension(file)}", i++);
}
}
}
If you allow to remove an Image from the ListView, you should also remove it from the ImageList: this implies that you need to re-index all the ListView Items starting from the Item that follows the one removed.
Remember to dispose of the Images you remove from the ImageList.

Loaded pictureBox.ImageLocation is null

I'm trying to do something when I click image displayed inside pictureBox1.
pictureBox is loaded with this code:
string imgpath = #"img\256.png";
pictureBox48.Image = Image.FromFile(imgpath);
Then control is released to me so I can see that the picture loaded correctly.
Then i click the picture:
public void pictureBox48_Click(object sender, EventArgs e)
{
string variable1 = pictureBox48.ImageLocation;
Form3 fo = new Form3(variable1);
fo.ShowDialog();
}
This doesn't work. When I debug the code I see that variable1 stay null, that is pictureBox48.ImageLocation is null. Why is that? Shouldn't it be the path to the image that is assigned there?
You can't get the image path when you set the image using the Image property because you are assigning an Image object which can come from different sources.
Set the image using ImageLocation.
string imgpath = #"img\256.png";
pictureBox48.ImageLocation = imgpath;
When you click in the PictureBox you can get the path using the same property:
public void pictureBox48_Click(object sender, EventArgs e)
{
string variable1 = pictureBox48.ImageLocation;
Form3 fo = new Form3(variable1);
fo.ShowDialog();
}
When dealing with Image or PictureBox I would recommend to not use something like Location or Path of the image. Assume that when the image is loaded user removes it from the hard drive and you're left with the code full of errors.
That's why you should rely on Image itself as it contains every information about the image like pixel format, width, height and raw pixel data.
I would recommend you to just copy the image, not the path to the file.
This piece of code should give you a hint:
pixtureBox48.Image = Image.FromFile(imgPath);
// above code assumes that the image is still on hard drive and is accessible,
// now let's assume user deletes that file. You have the data but not on the physical location.
Image copyImage = (Image)pictureBox48.Image.Clone();
Form3 fo = new Form(copyImage); // change .ctor definition to Form(Image copy)
fo.ShowDialog();

How do I get the Bitmap name when I click the image in datagridview?

I am trying to click on an image in a datagridview and then write its image/file name into a textbox so I can access this from elsewhere.
First I try just a small app to make sure I can make it all work. A Dialog contains the dataviewgrid and I put a bitmap into it as below:
public ChooseFormat()
{
InitializeComponent();
dataGridView1[0,0].Value = new Bitmap(#"C:\a\eggs\grid_app\grid_app\bin\Debug\graphics\1L5HQ60.bmp");
}
Now I click on the image but all the things I have tried I cannot get hold of the file name. The closest I get is below but this returns "System.Drawing.Bitmap" and not the file name. I am sure this must just be a tweak here to make it work but I have tried teh few things I know and nothing is working.
void DataGridView1CellContentClick(object sender, DataGridViewCellEventArgs e)
{
txtbx_choice.Text = dataGridView1[0,0].Value.ToString();
}
Drilling into the cells's data in the debugger doesn't bring up any info on the source of it. Maybe I have overlooked something..
One simple solution is to store the filename in the cell's Tag property:
string fileName = #"C:\a\eggs\grid_app\grid_app\bin\Debug\graphics\1L5HQ60.bmp";
dataGridView1[0,0].Value = new Bitmap(fileName );
dataGridView1[0,0].Tag = fileName ;
Now you can always access it:
string displayedFile = dataGridView1[0, someRow].Tag.ToString();
I have placed a Picture Box on the same form and this how I am displaying the ImageColumn's data (an Image ) in picture box
pictureBox1.Image = (Image)dataGridView1[0, 0].Value;

C# : List image reset after close app

I'm using VS2013 to develop an windows form application with SQL Server database.
I have a column in database table to store the image name :
In my application, I creat a button to select image from my computer and save that's image to application startup path :
private void buttonX1_Click(object sender, EventArgs e)
{
try
{
OpenFileDialog dlg = new OpenFileDialog();
dlg.Filter = "Image only. | *.jpg; *.jpeg; *png; *.gif;";
dlg.InitialDirectory = #"E:\";
dlg.Multiselect = false;
string a = null;
if (dlg.ShowDialog() == DialogResult.OK)
{
string[] tmp = dlg.FileNames;
foreach (string i in tmp)
{
FileInfo fi = new FileInfo(i);
string[] xxx = i.Split('\\');
string des = Application.StartupPath + #"\Images\" + xxx[xxx.Length - 1];
string desfolder = Application.StartupPath + #"\Images\";
imagename = xxx[xxx.Length - 1].ToString();
System.IO.Directory.CreateDirectory(desfolder);
File.Delete(des);
imageuploaded.Image = Image.FromFile(dlg.FileName);
//over.
fi.CopyTo(des);
imageList1.Images.Add(imagename, Image.FromFile(des));
//Process.Start("explorer.exe", desfolder);
}
MessageBox.Show("Thành công ");
}
}
catch (Exception ex) { MessageBox.Show(ex.Message); }
}
That code will load the image from computer, save to folder "images" in startup path and add image to imagelist1, too.
After that, I have a button to insert imagename to "Images" column (in SQL server database).
I have this code to use imagelist for my grid :
public PrdMan()
{
InitializeComponent();
GridPanel panel = superGridControl1.PrimaryGrid;
GridColumn column = panel.Columns["image"];
column.EditorType = typeof(MyGridImageEditControl);
column.EditorParams = new object[] { imageList1, ImageSizeMode.Zoom };
//superGridControl1.PrimaryGrid.Columns[8].Visible = false;
//superGridControl1.PrimaryGrid.Columns[2].CellStyles = "dd/MM/yyyy";
//styleManager1.ManagerStyle = eStyle.Metro;
//
//this.Location = new Point(0, 0);
//this.Size = Screen.PrimaryScreen.WorkingArea.Size;
}
And code to load grid :
this.mPhamTableAdapter.Fill(this.beautyMaDataSet.MPham);
this.superGridControl1.PrimaryGrid.DataSource = this.beautyMaDataSet.MPham;
My problem is : When I load image, and insert it into database's "Images" columns : It's success and grid will display image. But When I close app (after published) or stop debug (in VS) then re-open ( or debug again). The grid will not display my image
even though the image was still in folder :
And imagelist have no image in list :
I don't know what is my problem. Can you support me how to :
1/ Add image from PC to startup path's folder using C# and save image name to SQL server (to bind image to grid).
2/ Bind image from startup path's folder to imagelist and use it.
Thanks for support.
I sense two problems in your code, maybe some of them cause your problem.
First, if you load a table to a DataGridView (or something else), and update the GridView with your new image, but not write back to the database manually, the modification will not save to database.
As you said,
After that, I have a button to insert imagename to "Images" column (in SQL server database). I have this code to use imagelist for my grid
I guess one reason of your problem may relative to here.
Second, you used a dialog to select an image and copy to path "APP\Images", and store name to database. How will you do when the user run you application next time? Load the table and get image names, and find those images from the path?
Please provide the relative codes to solve your problem.
BTW, if the database is local, off-line DB, and also you won't store too many records, you may consider store your image raw-data in DB, too. (I know some people do not recommend this way, but in my opinion, it's one way to solve your problem too.)

Save Bitmap image

I'm trying to modify an example of a machine vision library ( Common Vision Blox ). The example gets an image from the camera, converts it to bitmap format and shows to the user through a PictureBox.
What I want it is to save the data to a file, but I get a BMP all in black. I tried some variants but the result is the same.
If I save the image from the PictureBox, using PictureBox.SaveImage the result is the same if I
The code is this :
private Bitmap _bm;
private bool _bRequiresCopy;
private void cvImg_ImageUpdated(object sender, EventArgs e)
{
// create a bitmap out of the image
_bm = CvbImageToBitmap(cvImg.Image, out _bRequiresCopy);
// and display it in the picture box
//if (_bm != null) // Only this two lines in the original code
// pictureBox.Image = _bm;
if (_bm != null)
{
pictureBox.Image = _bm;
// Tests to save
_bm.Save("c:\\test.bmp"); // This don't work
// The following don't work, but if add a button to the form and just place in the click
// event of the button it stores the image correctly
pictureBox.Image.Save("c:\\test2.bmp");
Bitmap TestBMP = new Bitmap(_bm);
TestBMP.Save("c:\\test3.bmp"); // This don't work
}
// setup grab checkbox
chkGrab.Enabled = cvImg.IsGrabber;
chkGrab.Checked = false;
}

Categories