I am writing a code in C# to show the unknown number of images from a specified folder into a "listview" I don't know how to get all the files present in that specific folder.
I know I have to use a loop and array but I don't know how.
Here is the code which I use to access files with the "known name of file".
It's a windows form app.
private void btnZoom_Click(object sender, EventArgs e)
{
ImageList imgs = new ImageList();
imgs.ImageSize = new Size(100, 100);
string[] paths = { };
paths = Directory.GetFiles("TestFolder");
try
{
foreach (string path in paths)
{
imgs.Images.Add(Image.FromFile(path));
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
listView1.SmallImageList = imgs;
listView1.Items.Add("2",0);
}
To get all the image files you can do
IEnumerable<string> paths = Directory.GetFiles(#"Your Dir", "*.*").Where(x=>x.EndsWith(".png") || x.EndsWith(".jpg")); //add all the extensions you wish in
then you can just iterate thru the list to add them in
Here is the working code:
and the code is :
private void button1_Click(object sender, EventArgs e)
{
listView1.Items.Clear();
imageList1.Images.Clear();
string[] pics = System.IO.Directory.GetFiles( "pics//");
listView1.View = View.SmallIcon;
listView1.SmallImageList = imageList1;
imageList1.ImageSize = new Size(64, 64);
foreach (string pic in pics)
{
imageList1.Images.Add(Image.FromFile(pic));
}
for (int j = 0; j < imageList1.Images.Count; j++)
{
ListViewItem item = new ListViewItem();
item.ImageIndex = j;
listView1.Items.Add(item);
}
}
and at designer set this:
Related
I have a piece of code which shows the pictures in a specific size. I want to get the real size of the pictures and want to show those pictures in their real size.
Can anybody help me in this matter.
Here is the piece of code which I am using to get the pictures.
private void btnZoom_Click(object sender, EventArgs e)
{
listView1.Items.Clear();
imageList1.Images.Clear();
string[] pics = System.IO.Directory.GetFiles("TestFolder//");
listView1.View = View.SmallIcon;
listView1.SmallImageList = imageList1;
imageList1.ImageSize = new Size(64, 64);
foreach (string pic in pics)
{
imageList1.Images.Add(Image.FromFile(pic));
}
for (int j = 0; j < imageList1.Images.Count; j++)
{
ListViewItem item = new ListViewItem();
item.ImageIndex = j;
listView1.Items.Add(item);
}
}
It's a Windows Form App.
Here's another approach...store the Image and its Full Path FileName in the Tag property of your ListViewItem using a Tuple<Image, String>.
Something like:
private void btnZoom_Click(object sender, EventArgs e)
{
listView1.Items.Clear();
imageList1.Images.Clear();
string[] pics = System.IO.Directory.GetFiles(#"C:\Users\mikes\Pictures\Facebook\Backyard Wildlife"); //"TestFolder//");
listView1.View = View.SmallIcon;
listView1.SmallImageList = imageList1;
imageList1.ImageSize = new Size(64, 64);
for(int i = 0; i < pics.Length; i++)
{
Image img;
using (FileStream fs = new FileStream(pics[i], FileMode.Open))
{
try
{
img = Image.FromStream(fs);
imageList1.Images.Add(img);
ListViewItem item = new ListViewItem();
item.ImageIndex = imageList1.Images.Count - 1;
item.Text = System.IO.Path.GetFileNameWithoutExtension(pics[i]);
item.Tag = new Tuple<Image, String>(img, pics[i]);
listView1.Items.Add(item);
}
catch (Exception ex) { };
}
}
}
private void btnView_Click(object sender, EventArgs e)
{
if (listView1.SelectedItems.Count > 0)
{
ListViewItem item = listView1.SelectedItems[0];
Tuple<Image, String> data = (Tuple < Image, String >)item.Tag;
label1.Text = data.Item2;
pictureBox1.Image = data.Item1;
Size sz = data.Item1.Size;
label2.Text = sz.ToString();
}
}
Initially I will be loading images(say 20 images) into a picturebox from a specified folder through selection from combobox dropdown, they get loaded normally into the picturebox.
The problem I am facing is when I select the next folder to acquire the image for processing, the previously selected folders images are also displayed in the picturebox after its count only the next folders images are displayed, I am unable to clear the previously loaded images.
To be specific, when I click on a folder from dropdown I want the particular folders image inside the picturebox I don't want the previously loaded images along with them. Am working in VS2013 with c#.
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
ArrayList alist = new ArrayList();
int i = 0;
int filelength = 0;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
DirectoryInfo di = new DirectoryInfo(#"C:\Users\Arun\Desktop\scanned");
DirectoryInfo[] folders = di.GetDirectories();
comboBox1.DataSource = folders;
}
private void button7_Click(object sender, EventArgs e)
{
if (i + 1 < filelength)
{
pictureBox1.Image = Image.FromFile(alist[i + 1].ToString());
i = i + 1;
pictureBox1.SizeMode = PictureBoxSizeMode.StretchImage;
}
}
private void button8_Click(object sender, EventArgs e)
{
if (i - 1 >= 0)
{
pictureBox1.Image = Image.FromFile(alist[i - 1].ToString());
pictureBox1.SizeMode = PictureBoxSizeMode.StretchImage;
i = i - 1;
}
}
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
string selected = comboBox1.SelectedItem.ToString();
String fullpath = Path.Combine(#"C:\Users\Arun\Desktop\scanned", selected);
DirectoryInfo di1 = new DirectoryInfo(fullpath);
DirectoryInfo[] folders1 = di1.GetDirectories();
comboBox2.DataSource = folders1;
}
private void button9_Click(object sender, EventArgs e)
{
string selected1 = comboBox1.SelectedItem.ToString();
string selected2 = comboBox2.SelectedItem.ToString();
//Initially load all your image files into the array list when form load first time
System.IO.DirectoryInfo inputDir = new System.IO.DirectoryInfo(Path.Combine(#"C:\Users\Arun\Desktop\scanned", selected1, selected2)); //Source image folder path
try
{
if ((inputDir.Exists))
{
//Get Each files
System.IO.FileInfo file = null;
foreach (System.IO.FileInfo eachfile in inputDir.GetFiles())
{
file = eachfile;
if (file.Extension == ".tif")
{
alist.Add(file.FullName); //Add it in array list
filelength = filelength + 1;
}
else if(file.Extension == ".jpg")
{
alist.Add(file.FullName); //Add it in array list
filelength = filelength + 1;
}
}
pictureBox1.Image = Image.FromFile(alist[0].ToString()); //Display intially first image in picture box as sero index file path
pictureBox1.SizeMode = PictureBoxSizeMode.StretchImage;
i = 0;
}
}
catch (Exception ex)
{
}
}
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if(e.KeyCode == Keys.D)
{
if (i + 1 < filelength)
{
pictureBox1.Image = Image.FromFile(alist[i + 1].ToString());
i = i + 1;
pictureBox1.SizeMode = PictureBoxSizeMode.StretchImage;
}
}
else if(e.KeyCode == Keys.A)
{
if (i - 1 >= 0)
{
pictureBox1.Image = Image.FromFile(alist[i - 1].ToString());
pictureBox1.SizeMode = PictureBoxSizeMode.StretchImage;
i = i - 1;
}
}
}
private void comboBox2_SelectedIndexChanged(object sender, EventArgs e)
{
}
}
}
Your code has many issues.
The one you are looking for is that you don't clear the alist before loading new file names.
So insert:
alist.Clear();
before
//Get Each files
And also
filelength = alist.Count;
after the loop. No need to count while adding!
Also note that ArrayList is pretty much depracated and you should use the type-safe and powerful List<T> instead:
List<string> alist = new List<string>();
Of course a class variable named i is silly and you are also relying on always having a SelectedItem in the comboBox2.
And since you are not properly Disposing of the Image you are leaking GDI resources.
You can use this function for properly loading images:
void loadImage(PictureBox pbox, string file)
{
if (pbox.Image != null)
{
var dummy = pbox.Image;
pbox.Image = null;
dummy.Dispose();
}
if (File.Exists(file)) pbox.Image = Image.FromFile(file);
}
It first creates a reference to the Image, then clears the PictureBox's reference, then uses the reference to Dispose of the Image and finally tries to load the new one.
I am using two comboboxes, in which 1st box will display folders in the specified location from that drop down list i will be selecting the necessary folder, so after selection the second combobox should list only the files depending on the 1st box's selected folder.(NOTE:Am not working with database, just accessing computers folder). Am working with visual studio 2013 in C#. Thanks in advance.
DirectoryInfo di = new DirectoryInfo(#"C:\Users\jeeva\Desktop\1234");
DirectoryInfo[] folders = di.GetDirectories();
comboBox1.DataSource = folders;
string selected =comboBox1.SelectedItem.ToString();
String fullpath = Path.Combine(#"C:\Users\jeeva\Desktop\1234", selected);
DirectoryInfo di1 = new DirectoryInfo(fullpath);
DirectoryInfo[] folders1 = di1.GetDirectories();
comboBox2.DataSource = folders1
It is done basically in 2 steps. You just need to separate them in your code.
1) get the folders into your combobox (may be already in the constructor of the Form):
DirectoryInfo di = new DirectoryInfo(#"C:\Users\jeeva\Desktop\1234");
DirectoryInfo[] folders = di.GetDirectories();
comboBox1.DataSource = folders;
2) double click comboBox1 in the designer. This will create an event which is triggered when the user selects an item. Inside it you can then get all the subfolders and give them as DataSource to the ComboBox which shall display them.
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
string selected =comboBox1.SelectedItem.ToString();
String fullpath = Path.Combine(#"C:\Users\jeeva\Desktop\1234", selected);
DirectoryInfo di1 = new DirectoryInfo(fullpath);
DirectoryInfo[] folders1 = di1.GetDirectories();
comboBox2.DataSource = folders1
}
You can use Directory.GetFiles("folderName") method to populate your second combobox. Directory class resides in System.IO namespace.
You can get the folder list by something like this:
DirectoryInfo obj = new DirectoryInfo("E:\\");//you can set your directory path here
DirectoryInfo[] folders = obj.GetDirectories();
YourDirCombo.DataSource = folders ;
You probably have a method listening to your first combo changes:
private void YourDirCombo_SelectedIndexChanged(object sender, EventArgs e)
now in this you can get the files of the selected folder:
string [] fileEntries = Directory.GetFiles(YourDirCombo.SelectedValue);
YourFileCombo.DataSource = fileEntries;
The following can be optimized and generalized in several different ways - I'm doing it "long hand" to give you the most information possible.
private void initializeComboBoxes()
{
ComboBox c = new ComboBox();
c.Name = "cbx_One";
c.Items.Add("Select a File");
foreach(string direc in System.IO.Directory.GetDirectories(#"PathToYourFiles"))
{
c.Items.Add(direc);
}
c.SelectedIndex = 0;
c.SelectedIndexChanged += loadComboBox2;
Controls.Add(c);
ComboBox c1 = new ComboBox();
c1.Name = "cbx_Two";
c1.Items.Add("Waiting for file selection");
c1.SelectedIndex = 0;
c1.SelectedIndexChanged += loadFile;
Controls.Add(c1);
areComboBoxesUpdating = false;
}
bool areComboBoxesUpdating = true;
protected void loadComboBox2(object sender, EventArgs e)
{
if (!areComboBoxesUpdating)
{
ComboBox c1 = sender as ComboBox;
ComboBox c2 = Controls.Find("cbx_Two", true)[0] as ComboBox;
c2.Items.Clear();
if (c1.SelectedIndex == 0)
{
c2.Items.Add("Waiting for file selection");
}
else
{
c2.Items.Add("Please select a file");
//assuming c1 is the list of directories
foreach (string file in System.IO.Directory.GetFiles(c1.SelectedItem.ToString()))
{
c2.Items.Add(Path.GetFileName(c1.SelectedItem.ToString()));
}
}
areComboBoxesUpdating = true;
c2.SelectedIndex = 0;
areComboBoxesUpdating = false;
}
}
protected void loadFile(object sender, EventArgs e)
{
//a selection has been made from the second box - you have directory in box1 and filename in box2
ComboBox c = sender as ComboBox;
if (c.SelectedIndex > 0)
{
string directory = ((ComboBox)Controls.Find("cbx_One", true)[0]).SelectedItem.ToString();
string file = c.SelectedItem.ToString();
//do something
}
}
On the Onchange event of Combobox1:
ComboBox2.dataSource = System.IO.Directory.GetFiles(ComboBox1.SelectedText)
This should populate all the files in Combobox2
I'm trying to make a button which upon being pressed will get all the images in a directory and place them in order in an array of images , I have it working so far where it can get the file paths but I cant get it working for images , any ideas ?
here is the code i'm trying to use
private void button2_Click(object sender, RoutedEventArgs e)
{
string[] filePaths =Directory.GetFiles("C:/Users/Pictures/Movements/","*.jpg");
System.Windows.Controls.Image[] Form_moves =new System.Windows.Controls.Image[12];
int i = 0;
foreach (string name in filePaths)
{
Console.WriteLine(name);
Form_moves[i] = filePaths[i] ;
i++;
}
string[] UserFilePaths = Directory.GetFiles("C:/Users/Pictures/Movements/User/", "*.jpg");
foreach (string User_Move_name in filePaths)
{
Console.WriteLine(User_Move_name);
}
}
I think I've solved it :
private void button2_Click(object sender, RoutedEventArgs e)
{
string[] filePaths = Directory.GetFiles("C:/Users/Movements/Form/","*.jpg");
string[] User_Moves_filePaths = Directory.GetFiles("C:/Users/Movements/User/", "*.jpg");
System.Drawing.Image[] Form_Move = new System.Drawing.Image[9];
System.Drawing.Image[] User_Move = new System.Drawing.Image[9];
int i = 0;
int j = 0;
foreach (string name in filePaths)
{
Console.WriteLine(name);//Kept in for testing purposes SolidBrush Image CancelEventArgs see that array is being populated in correct order
Form_Move[i] = System.Drawing.Image.FromFile(filePaths[i]);
i++;
}
foreach (string User_Move_name in User_Moves_filePaths)
{
Console.WriteLine(User_Move_name);
User_Move[j] = System.Drawing.Image.FromFile(User_Moves_filePaths[j]);
j++;
}
I am working in C# WinForms. I have made a Windows Explorer that displays the logical directories and then when clicked on them, it shows the files in them in a ListView (old but tricky thing). I get the icons from the system, using:
Icon iconForFile = SystemIcons.WinLogo;
ListViewItem lv = new ListViewItem(filData, imageList1.Images.Count);
lv.Tag = file;
iconForFile = Icon.ExtractAssociatedIcon(file);
string Extension = Path.GetExtension(file);
if (!imageList1.Images.ContainsKey(file))
{
// If not, add the image to the image list.
iconForFile = System.Drawing.Icon.ExtractAssociatedIcon(file);
imageList1.Images.Add(file, iconForFile);
}
lv.ImageKey = file;
listView1.SmallImageList = imageList1;
Now the problem is this: it does show the icons when a directory at first-level is clicked but when I click the folders in any directory (ie. "C"), it doesn't show the icons in the subfolders of a directory. Please help me on how I can customize it. My full code is somewhat like this:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
PopulateTreeView(treeView1);
}
private void PopulateTreeView(TreeView tv)
{
string[] drives = Environment.GetLogicalDrives();
TreeNode MyCnode = new TreeNode();
MyCnode = new TreeNode("My Computer");
tv.Nodes.Add(MyCnode);
foreach (string drive in drives)
{
TreeNode nodeDrive = new TreeNode();
nodeDrive.Tag = drive;
nodeDrive.Text = drive;
tv.Nodes.Add(nodeDrive);
// tv.Nodes.Add();
// nodeDrive.EnsureVisible();
// treeView1.Refresh();
try
{
//add dirs under drive
if (Directory.Exists(drive))
{
foreach (string dir in Directory.GetDirectories(drive))
{
TreeNode node = new TreeNode();
node.Tag = dir;
node.Text = dir.Substring(dir.LastIndexOf(#"\") + 1);
node.ImageIndex = 1;
nodeDrive.Nodes.Add(node);
}
}
}
catch (Exception)
{
}
MyCnode.Expand();
}
}
public TreeNode GetDirectory(TreeNode parentNode)
{
DirectoryInfo d = new DirectoryInfo(parentNode.FullPath);
DirectoryInfo[] dInfo = d.GetDirectories()
.Where(di => !di.Attributes.HasFlag(FileAttributes.System))
.Where(di => !di.Attributes.HasFlag(FileAttributes.Hidden))
.ToArray();
parentNode.Nodes.Clear();
if (dInfo.Length > 0)
{
TreeNode treeNode = new TreeNode();
foreach (DirectoryInfo driSub in dInfo)
{
treeNode = parentNode.Nodes.Add(driSub.Name);
treeNode.Nodes.Add("");
}
}
return parentNode;
}
private void AddFiles(string strPath)
{
try
{
listView1.BeginUpdate();
listView1.Items.Clear();
//headers listview
// listView1.Columns.Add("File Name", 200);
//listView1.Columns.Add("Size", 80);
//listView1.Columns.Add("Last Accessed", 110);
string[] dirData = new string[3];
string[] filData = new string[3];
string[] files = Directory.GetFiles(strPath);
foreach (string file in files)
{
FileInfo finfo = new FileInfo(file);
FileAttributes fatr = finfo.Attributes;
string name = Path.GetFileNameWithoutExtension(file);
filData[0] = name;
filData[1] = finfo.Length.ToString();
filData[2] = File.GetLastAccessTime(file).ToString();
// Set a default icon for the file.
Icon iconForFile = SystemIcons.WinLogo;
ListViewItem lv = new ListViewItem(filData, imageList1.Images.Count);
lv.Tag = file;
iconForFile = Icon.ExtractAssociatedIcon(file);
string Extension = Path.GetExtension(file);
if (!imageList1.Images.ContainsKey(file))
{
// If not, add the image to the image list.
iconForFile = System.Drawing.Icon.ExtractAssociatedIcon(file);
imageList1.Images.Add(file, iconForFile);
}
lv.ImageKey = file;
listView1.SmallImageList = imageList1;
listView1.Items.Add(lv);
}
}
catch (Exception Exc) { MessageBox.Show(Exc.ToString()); }
listView1.EndUpdate();
}
private void listView1_MouseDoubleClick(object sender, MouseEventArgs e)
{
string pathdoubleClicked = listView1.FocusedItem.Tag.ToString();
Process.Start(pathdoubleClicked);
}
private void treeView1_AfterExpand(object sender, TreeViewEventArgs e)
{
GetDirectory(e.Node);
treeView1.SelectedNode.Expand();
AddFiles(e.Node.FullPath.ToString());
}
}
for anyone still seeing this as an answer to a search, the assignment of the imagelist needs to be done before the items are added to the imagelist.
private void AddFiles(string strPath)
{
try
{
listView1.BeginUpdate();
listView1.Items.Clear();
listView1.SmallImageList = imageList1;