How to load image to PictureBox list - c#

I am loading images like this:
image = Image.FromFile(//here goes path to image);
Than i have list of pictureBoxes like this
List<PictureBox> pictureBoxes = new List<PictureBox>();
Than i load picture boxes in pictureBox list like this
// i is set to one
for (; i < this.images.Count; i++)
{
pictureBoxes.Add((PictureBox)Controls.Find("pictureBox" + i.ToString(), true)[0]);
}
And now I want to load that image in pictureBox[0]. Then I load another image and I want to add it to pictureBox[1] and so on. I am trying to do this more than 3 days. Does anyone know how to do it?

After you filled your picturebox list, just find the first empty one.
var emptyPb = pictureBoxes.Where(x => x.Image == null).FirstOrDefault();
if(emptyPb==null)
{
throw new Exception("No empty picturebox could be found!");
return;
}
emptyPb.Image = images[0];

//Set the number of images you have.
int imageCount = 3;
//Create path.
string path = #"C:\ImageFolder\";
//Create the List of PictureBox
List<PictureBox> pictureBoxes = new List<PictureBox>();
//This for will create the name foreach image.
//Example: "pic1", "pic2", "pic3".
//Assuming that you have the names of each file image like the example.
for (int i = 1; i < imageCount + 1; i++)
{
//Create a PictureBox foreach image
PictureBox pictureBox = new PictureBox()
{
Name = $"pic{i}",
//Assign the image file.
Image = Image.FromFile(path + $"pic{i}.jpg")
};
//Add the new pictureBox to the list pictureBoxes
pictureBoxes.Add(pictureBox);
}

Related

C# code displays picture boxes vertically instead of horizontally

My code in C# displays picture boxes vertically where the second picture box is below the first one instead of displaying the second picture box horizontally next to the first such that when the width of the visible form overflows. the code creates a new row and continues to create picture boxes. The code reads image file paths from a folder and initializes an array of picture boxes based on the count of the images. The goal is to create a grid of picture boxes for displaying the images. How can I update the logic of the app to make it achieve the desired output.
public class ImageGrid:Form {
//declare the folder name that contains the complex images
private string _folder = "./Complex"; //declare the array of picture boxes to display in the form
private PictureBox[] _image_grid;
private List<string> _paths= new List<string>();
public ImageGrid() {
//set a title for the form
Text = "Confidence Level Checker";
//make the screen full
FormBorderStyle =
FormBorderStyle.None;
WindowState =
FormWindowState.Maximized;
//read all the image names in the folder
if (Directory.Exists(_folder)) {
//list all the files in the folder
string[] files =
Directory.GetFiles(_folder);
if (files != null && files.Length > 0) {
//add the paths to the list
foreach (var path in files) {
_paths.Add(path);
}
//create an array of picture boxes based on the file count
_image_grid = new PictureBox[files.Length];
//declare the size of each picture box
int width = 300; int height = 250;
int x = 20; int y = 20;
foreach (string path in _paths) {
PictureBox box = new PictureBox()
{
Size = new Size(width, height),
Location = new Point(x,y),
Image = Image.FromFile(path),
SizeMode = PictureBoxSizeMode.StretchImage
};
//add the picture box to the form
this.Controls.Add(box);
//update the location to draw the picture box
x += 320;
if (x + 300 > ClientSize.Width) { x = 20; y += 270; }
}
}
}
}
You can use a FlowLayoutPanel() instead to make this simpler.
Then ensure (in the form designer) that the property FlowDirection is set to LeftToRight.
You can also do this in code:
myFlowLayoutPanel.FlowDirection = FlowDirection.LeftToRight;
You add controls to a FlowLayoutPanel the same way you do to a standard Panel:
myFlowLayoutPanel.Add(someControl);

How to get Images from database to Listview c#

I want to get database images show in listview but it does not work . I tried but can't any one can help .
ListViewItem liv = new ListViewItem(read[0].ToString());
liv.SubItems.Add(read[1].ToString());
liv.SubItems.Add(read[2].ToString());
liv.SubItems.Add(read[3].ToString());
listView1.Items.Add(liv);
Here on index[3] in database the images stored .
The error show in image
For what I can see, your image is stored in a Database and retrieved in ByteArray format. You need to convert the ByteArray stream to a Bitmap Image:
Image _image = new Bitmap(new MemoryStream((Byte[])read[3]));
Since this image has to be referenced in more than one method, define it at Class level.
using System.Drawing;
using System.Drawing.Text;
Image _image;
To let a SubItem display the image, you need to Paint the items yourselft, so set the OwnerDraw property of your ListView:
listView1.OwnerDraw = true;
Get the items from your Data source:
(... LOOP ...)
//Define a new ListView Item...
ListViewItem _LVItem = new ListViewItem(read[0].ToString());
ListViewItem.ListViewSubItemCollection _ItemsCollection =
new ListViewItem.ListViewSubItemCollection(_LVItem);
//... and SubItems
_ItemsCollection.Add(new ListViewItem.ListViewSubItem(_LVItem, read[1].ToString()));
_ItemsCollection.Add(new ListViewItem.ListViewSubItem(_LVItem, read[2].ToString()));
//No text here, this is where the image will be drawn
_ItemsCollection.Add(new ListViewItem.ListViewSubItem(_LVItem, ""));
//Create a new Bitmap using a MemoryStream
_image = new Bitmap(new MemoryStream((Byte[])read[3]));
listView1.Items.Add(_LVItem);
(... LOOP ...)
Create EventHandlers for listView1.DrawColumnHeader and listView1.DrawSubItem
//You need to draw both Headers...
private void listView1_DrawColumnHeader(object sender, DrawListViewColumnHeaderEventArgs e)
{
e.Graphics.TextRenderingHint = TextRenderingHint.ClearTypeGridFit;
//Let the system draw these headers, nothing to do here
e.DrawDefault = true;
}
//... and SubItems
private void listView1_DrawSubItem(object sender, DrawListViewSubItemEventArgs e)
{
//If this is the column where the image is shown, draw it
if (e.ColumnIndex == 3)
{
//Position the image in the middle of its Column
//This will be re-calculated when the Column is resized
int _XLocation = (e.SubItem.Bounds.X +
(e.SubItem.Bounds.Width / 2) -
(e.SubItem.Bounds.Height / 2));
//Draw the Image resized to the Height of the row
e.Graphics.DrawImage(_image, new Rectangle(_XLocation, e.SubItem.Bounds.Y, e.SubItem.Bounds.Height, e.SubItem.Bounds.Height));
}
//Draw the other columns using their pre-defined values
e.Graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;
e.Graphics.DrawString(e.SubItem.Text,
e.SubItem.Font,
new SolidBrush(e.SubItem.ForeColor),
e.SubItem.Bounds.Location.X,
e.SubItem.Bounds.Location.Y);
}
And this is the result:
// To Convert you byte array to Images you need to convert it to a memory stream first
// You will need to add:
// using System.IO;
// And you need to add an ImageList named "imageList1" to your form.
// Then Initialize the ImageList object with images.
for (int i = 0; i < read.Length; i++)
{
try
{
MemoryStream memStream = new MemoryStream(read[i]);
this.imageList1.Images.Add(Image.FromStream(memStream));
}
catch
{ MessageBox.Show( "Image at index ( " + i.ToString() + " ) is not an image file"); }
}
//Now You can assign the ImageList objects to your ListView.
this.listView1.View = View.SmallIcon;
this.listView1.SmallImageList = this.imageList1;
for (int j = 0; j < this.imageList1.Images.Count; j++)
{
ListViewItem liv = new ListViewItem();
liv.ImageIndex = j;
this.listView1.Items.Add(liv);
}

Print multiple barcode images

I have created the windows application to generate bar-code.
I am generating multiple bar-code images and saving them in a folder now i want to display all of them in the picture box and print them help..
Dynamically create the picture box and add to form.
See the sample code:
private void LoadPic()
{
string path = #"Path here";
PictureBox pic;
FlowLayoutPanel panel;
int x = 0;
int y = 0;
foreach ( string item in Directory.GetFiles ( path ) )
{
pic = new PictureBox ();
panel = new FlowLayoutPanel ();
panel.Location = new Point ( x, y );
pic.Size = new System.Drawing.Size (100, 100 );
pic.ImageLocation = item;
panel.Controls.Add ( pic );
pic.Click +=pic_Click;
panel1.Controls.Add ( panel );
y = y + 100;
}
}

Multiply images boxes

I have a simple form with 10 picture boxes like: pictureBox1, pictureBox2, pictureBox3...
And I have a folder with 10 images like: image1, image2, image3...
Now I am smart enough to know that I don't want to hard code pictureBox1.ImageLocation = image1, pictureBox2.ImageLocation = image2... Rather, I need to create some kind of loop or array that will populate my picture boxes with their respective images, but I am not smart enough to figure out how.
Something like:
for (int i = 0; i < 10; i++)
{
pictureBox[i].ImageLocation = image[i];
}
Eventually, I was hoping this project would scale dynamically, if I have a file with say 12 images, the program will simply create 12 picture boxes and load the images. A little help would be great.
What you have there would roughty work though I would suggest a list.
List<PictureBox> pictureBoxes = new List<PictureBox>();
List<Image> images = new List<Image>();
//code to populate your lists
for (int i = 0; i < pictureBoxes.Count; i++)
{
pictureBoxes[i].Image = images[i];
}
If you want to make sure you have enough images for your PictureBox list you could check ahead of time:
if (images.Count >= pictureBoxes.Count)
{
for (int i = 0; i < pictureBoxes.Count; i++)
{
pictureBoxes[i].Image = images[i];
}
}
...or fill out as many as you can before running out of images.
for (int i = 0; i < pictureBoxes.Count && i < images.Count; i++)
{
pictureBoxes[i].Image = images[i];
}
EDIT:
So if you want to use strings to set the location of the images instead you can do that. Check this out:
List<PictureBox> pictureBoxes = new List<PictureBox>();
List<string> imageLocations = new List<string>();
private void Form1_Load(object sender, EventArgs e)
{
PictureBox PB1 = new PictureBox();
PB1.Location = new Point(0, 0);
PB1.Size = new Size(144, 197);
Controls.Add(PB1);
PictureBox PB2 = new PictureBox();
PB2.Location = new Point(145, 0);
PB2.Size = new Size(327, 250);
Controls.Add(PB2);
pictureBoxes.Add(PB1);
pictureBoxes.Add(PB2);
imageLocations.Add(#"C:\PicExample\image1.jpg");
imageLocations.Add(#"C:\PicExample\image2.jpg");
for (int i = 0; i < pictureBoxes.Count && i < imageLocations.Count; i++)
{
pictureBoxes[i].ImageLocation = imageLocations[i];
}
}
EDIT for Iteratively Creating PictureBoxe List:
If you want to not have to worry about hard-coding your list (and your picture boxes will be the same size) you could do something like this:
for (int i = 0; i < HoweverManyPictureBoxesYouWant; i++)
{
PictureBox PB = new PictureBox();
PB.Name = "PB" + i.ToString();
PB.Location = new Point(250 * i, 0); //Edit this as you see fit for location, i'm just putting them in a row
PB.Size = new Size(250, 250);
PB.ImageLocation = #"C:\PicExample\image" + i.ToString() + ".jpg";
Controls.Add(PB);
pictureBoxes.Add(PB); //You only need to do this if you want the PB's in a list for other reasons than setting the image location
}

Add picture boxes dynamically in row

I am trying to show images in a row..For this I am trying to add picture boxes dynamically. Image location is stored in databses. my code is as
int iCtr = 0;
for (int i = 0; i < dt.Rows.Count; i++)
{
PictureBox picture = new PictureBox
{
Name = "pictureBox"+i,
Size = new Size(316, 320),
Location = new Point(1, iCtr * 1100 + 1),
Visible = true
};
// string fname = dt.Rows[2]["FileName"].ToString();
picture.ImageLocation = dt.Rows[i]["FileName"].ToString();
//#"..\Images\80knhk00003.jpg";
pnlDisplayImage.Controls.Add(picture);
iCtr++;
}
where dt is datable.
with this I can see only last image but not all images. Even last image is very small and complete image is not shown.(i.e. I can view only one corner of actual image).
How can I give size to image so that it can be viewed completely?
And how can I display images in row?
Please help
Thanks
Can you try something like this? To get the scaling, see PictureBoxSizeMode.
List<PictureBox> pictureBoxList = new List<PictureBox>();
for (int i = 0; i < dt.Rows.Count; i++)
{
PictureBox picture = new PictureBox
{
Name = "pictureBox" + i,
Size = new Size(316, 320),
Location = new Point(i * 316, 1),
BorderStyle = BorderStyle.FixedSingle,
SizeMode = PictureBoxSizeMode.Zoom
};
picture.ImageLocation = dt.Rows[i]["FileName"].ToString();
pictureBoxList.Add(picture);
}
foreach (PictureBox p in pictureBoxList)
{
pnlDisplayImage.Controls.Add(p);
}
instead of Image property, set the BackGroundImage property to your picture location, and then set the BackGroundImageLayout to the value "Stretch" then you will see full image.

Categories