ladowanie zdjec z katalogu

0

Witam chce zaladowac zdjecia z wybranego katalogu...oczywiscie najlepiej zeby byly one w tabeli wiec probowalem uzyc TableLayoutPanel i jego wlascisco backgroundImage...jednak dostaje blad...


        private void otworzKatalogToolStripMenuItem_Click(object sender, System.EventArgs e)
        {
            ArrayList path = new ArrayList();
            string folder;
            int filesCount = 0;
            float maxRows;

            this.folderBrowserDialog1 = new System.Windows.Forms.FolderBrowserDialog();
            this.folderBrowserDialog1.ShowNewFolderButton = false;
            this.folderBrowserDialog1.RootFolder = System.Environment.SpecialFolder.MyComputer;
            DialogResult result = this.folderBrowserDialog1.ShowDialog();
            folder = folderBrowserDialog1.SelectedPath;

            if (result == DialogResult.OK)
            {
                foreach (string file in System.IO.Directory.GetFiles(folder))
                {
                    path.Add(file);
                    filesCount++;
                }

                //layout
                this.tableLayoutPanel1 = new TableLayoutPanel();
                this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 27);
                this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 50F));
                this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 50F));
                this.tableLayoutPanel1.ColumnCount = 3;
                maxRows = filesCount / this.tableLayoutPanel1.ColumnCount;
                this.tableLayoutPanel1.RowCount = Convert.ToInt32(Math.Round(maxRows));

                for(int i = 0; i <= path.Count; i++)
                    this.tableLayoutPanel1.BackgroundImage = System.Drawing.Image.FromFile(Convert.ToString(path[i])); //tu jest blad out of memory

            }
        }

A wiec tak mam pare pytan...
Czy dobrze tworze dynamicznie kolumny i wiersze...?
Czy jest to wydajny sposob?Bo poki co nie dziala wiec nie wiem jak szybko dziala...
Jak molgbym dodac do komorek TableLayoutPanel kontrolke picturebox bo wolalbym do niej ladowac zdjecia...

W czym tkwi problem...?

0

Czego nie rozumiesz w "out of memory"?
Podmieniasz background w całej kontrolce TableLayoutPanel, a nie w komórce.
Przy którym obrazku rzuca ci taki błąd, bo widzę że ładujesz wszystkie z jakiegoś katalogu. Ile ważą te obrazki?
W dokumentacji masz opisane kiedy OutOfMemoryException jest rzucany.
http://msdn.microsoft.com/en-us/library/stf701f5.aspx
Wczytywanie pliku weź w try-catch i obsłuż przypadek kiedy leci taki exception i zamiast obrazka pokazuj jakiś komunikat że jest jakiś problem z obrazkiem.
Łykasz wszystkie pliki z katalogu, bez żadnej maski i ograniczenia tylko dla plików graficznych, pewnie m.in. próbujesz ładować Thumbs.db.

0

No to miedzy innymi zapytalem jak dac obrazki jako tla komorek a nie calej tabeli...
to sa zwykle obrazki z moje dokumenty ;]
hmm albo jeszcze lepiej...jak moge uzyskac efekt tabeli uzywajac picturebox...jak go rozmiescic na formie 3 w rzedzie...?

edit: problem z maska rozwiazany...!

0

W TableLayoutPanel nie ma takiej opcji. Możesz stworzyć własną kontrolkę gdzie będziesz sam rysował albo użyć Paneli z odpowiednimi Dock i/lub Anchor.
Albo łatwiej użyj nieedytowalnego grid'a.

0

Problem rozwiazalem inaczej...moze i na okolo ale latwo i dziala...
Mam tylko 2 pytania...
10 zdjec laduje mi sie kilkanascie sekund jak zoptymalizowac ten kod:


        private void otworzKatalogToolStripMenuItem_Click(object sender, System.EventArgs e)
        {

            ArrayList path = new ArrayList();
            string[] extension = { "*.jpg", "*.jpeg", "*.bmp", "*.gif" };
            string folder;

            this.folderBrowserDialog1 = new System.Windows.Forms.FolderBrowserDialog();
            this.folderBrowserDialog1.ShowNewFolderButton = false;
            this.folderBrowserDialog1.RootFolder = System.Environment.SpecialFolder.MyComputer;
            DialogResult result = this.folderBrowserDialog1.ShowDialog();
            folder = folderBrowserDialog1.SelectedPath;

            if (result == DialogResult.OK)
            {
                foreach(string ext in extension) {

                    foreach (string file in System.IO.Directory.GetFiles(folder, ext))
                    {
                        path.Add(file);
                    }
                }

                this.p = Convert.ToString(path[0]);

                int x = 10;
                int y = 40;
                int thumbX = 150;
                int thumbY = 150;
                float elementForRows = this.Width / thumbX;
                elementForRows = Convert.ToInt32(Math.Round(elementForRows));

                for (int i = 0; i <= 10; i++)
                {
                    PictureBox pictureBox = new PictureBox();
                    pictureBox.Cursor = System.Windows.Forms.Cursors.Hand;
                    pictureBox.Location = new System.Drawing.Point(x, y);
                    pictureBox.SizeMode = PictureBoxSizeMode.StretchImage;
                    pictureBox.Size = new System.Drawing.Size(thumbX, thumbY);
                    pictureBox.Image = new System.Drawing.Bitmap(Convert.ToString(path[0]));
                    pictureBox.Click += new EventHandler(this.pictureBox_Click);
                    Controls.Add(pictureBox);

                    if ((i+1) % elementForRows == 0)
                    {
                        x = 10;
                        y += 160;
                    }
                    else
                        x += 160;
                }
            }
        }

I potem dla kazdego zdj. mam event Click jak przeslac do niego sciezke zdj. zaleznie na ktory picturebox sie kliknie poki co mam tak:


        private void pictureBox_Click(object sender, EventArgs e)
        {
            Form showPicture = new Form();
            PictureBox picture = new PictureBox();

            showPicture.WindowState = System.Windows.Forms.FormWindowState.Maximized;
            picture.SizeMode = PictureBoxSizeMode.StretchImage;
            picture.Dock = DockStyle.Fill;
            picture.Image = new System.Drawing.Bitmap(this.p);
            showPicture.Controls.Add(picture);
            showPicture.Show();
        }

jak widac mam na stale w polu p jedna sciezke jak przypisac kazdemu zdarzeniu wlasna sciezke...?

btw: i mam jeszcze jeden problem gdy do picturebox'a proboje ladowac rozne zdj czyli:

pictureBox.Image = new System.Drawing.Bitmap(Convert.ToString(path[i]));

DOstaje blad:

Index was out of range. Must be non-negative and less than the size of the collection.
Parameter name: index

Z jakiej racji...?

0

1) Czemu używasz ArrayList zamiast List<string>?
2) Tworzysz w pętli obiekty PictureBox, co jest wolne.
3) Do każdego z tych PictureBoxów ładujesz dużą bitmapę, co jest jeszcze wolniejsze.

0

ad 1. masz racje zmienie to!
ad 2. to mam tworzyc obiekt picturebox poza petla...?a skad mam wiedziec ile mam ich stworzyc...?
ad 3. lacznosc fotek to 5,5mb...wiec raczje nie duzo....to co mam robic przeskalowywac kazde zdjecie w locie...?wydaje mi sie to jeszcze mniej wydajne...dlaczego np windowsowa przegladarka zdj potrafi zaladowac katalog ktory ma 1gm zdjec w kilkanascie sekund...?

0

2) IMHO lepiej byłoby tych PictureBoxów w ogóle nie tworzyć. Na pewno aż tyle ich Ci potrzeba?
3) Przeglądarka zdaje się jakoś cacheuje sobie miniaturki zdjęć i potem je wczytuje.

0

nom a ile mam ich stworzyc 5 gdy np w katalogu mam 20 zdj....?
no to tak ogolnie jest jakies rozwiazanie na moj problem...?
i jak moge przeslac do ClickMouse sciezke obrazka..?

0
marcio napisał(a)

ad 1. masz racje zmienie to!
ad 2. to mam tworzyc obiekt picturebox poza petla...?a skad mam wiedziec ile mam ich stworzyc...?

Ja tam się nigdy w formsach nie bawiłem ale pierwsze co mi przychodzi do głowy to:

            DirectoryInfo dir = new DirectoryInfo("jakaś ścieżka");
            var files = dir.GetFiles("*.jpg");
            foreach (var file in files)
            {
                PictureBox p = new PictureBox();
                p.Image = new Bitmap(file.Name);
            }

i tworzysz dokładnie tyle ile trzeba. Chyba, że tak robiłeś, a ja nie doczytałem, to olej tą wypowiedź, trochę późno już jest.

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0