PDA

View Full Version : سوال: ریختن عکس از ImageList درون ListView



D3M3NT0R
یک شنبه 14 دی 1393, 02:17 صبح
سلام دوستان
من یه برنامه دارم که اول میاد یه imageList رو با عکس پر میکنه بعد عکس هارو تک تک وارد imageList میکنه
ولی یه مشکل هست
موقع پر کردن imageList خیلی از ram سیستم استفاده میشه چون پرونده هایی که خونده میشه خیلی سنگین هستن
حتی شده تا 3 گیگ از ram استفاده کنه
بعضی موقع ها هم out of memory میشه

کد برنامه به این شکل هست




DirectoryInfo dir = new DirectoryInfo(path);

foreach (FileInfo file in dir.GetFiles())
{
try
{
this.imageList1.Images.Add(Image.FromFile(file.Ful lName));
}
catch{
Console.WriteLine("This is not an image file");
}
}
this.listView1.View = View.LargeIcon;
this.imageList1.ImageSize = new Size(32, 32);
this.listView1.LargeImageList = this.imageList1;
//or
//this.listView1.View = View.SmallIcon;
//this.listView1.SmallImageList = this.imageList1;


for (int j = 0; j < this.imageList1.Images.Count; j++)
{
ListViewItem item = new ListViewItem();
item.ImageIndex = j;
this.listView1.Items.Add(item);
}



من واسه اینکه مشکل ram رو حل کنم این قسمت کد رو تغییر دادم



Image img=Image.FromFile(file.FullName);
this.imageList1.Images.Add(img);
img.Dispose();


حالا که مشکل ram حل میشه دیگه عکس هارو داخل listView نشون نمیده
اسمشون میاد ولی خوده عکس نه

از کد System.GC.Collect() استفاده کردم ولی به دردم نمیخوره
بازم از ram کلی استفاده میکنه آخرش که کار تموم شد ram رو خالی میکنه

میخواستم بدونم کسی راه حلی نداره ؟

ممنون

khokhan
یک شنبه 14 دی 1393, 18:59 عصر
هیچکی راهی بلد نیس ؟:ناراحت:
بهترین کار اینه که تصاویر رو از بیرون از برنامه و یک مسیر مشخص بخونه و بریزه توی لیست
و یک مکانیزم صفحه بندی هم داشته باشه تا هر بار مثلا ده یا بیست تصویر رو نشون بده

mojtabamalaekeh
یک شنبه 14 دی 1393, 19:13 عصر
مشکل از imageList نیست. RAM و PageFile محدود هستن. من به تعداد زیاد خواستم pictureBox ایجاد کنم بعد از پر شدن pageFile که داشتم با TaskManager نگاش میکردم خطا میداد.

شما نمونه های کوچولو از عکس بساز و مسیر فایل ها رو هم توی یک آرایه ذخیره کن که هرجا لازم شد نمونه اصلی رو Load کنی.

Image img = Image.FromFile(file.FullName);
int w, h;
if (img.Width > img.Height)
{
w = thumbSize;
h = img.Height * thumbSize / img.Width;
}
else
{
h = thumbSize;
w = img.Width * thumbSize / img.Height;
}
Image thumb = img.GetThumbnailImage(w, h, () => false, IntPtr.Zero);
img.Dispose();
this.imageList1.Images.Add( thumb);

این رو هم خارج از حلقه تعریف کن و بجای 32 مقدار دلخواه بده:

int thumbSize = 32;

این کدها برای این هستن که تناسب عکس (نسبت طول به عرض) به هم نخوره. کمی سرعت رو پایین میاره ولی ارزشش رو داره.
اصلا بیا اول لیست مسیر فایل ها رو بساز که بعد پر شدن لیست بدونی با چه تعداد عکس سر و کار داری.
تعداد فایل های عکس رو که بدونی میشه ProgressBar یا هر ایده ی دیگه ای برا راضی نگه داشتن کاربر در حین ایجاد thumbnailها پیاده سازی کنی.

D3M3NT0R
جمعه 19 دی 1393, 00:42 صبح
این کدها برای این هستن که تناسب عکس (نسبت طول به عرض) به هم نخوره. کمی سرعت رو پایین میاره ولی ارزشش رو داره.
اصلا بیا اول لیست مسیر فایل ها رو بساز که بعد پر شدن لیست بدونی با چه تعداد عکس سر و کار داری.
تعداد فایل های عکس رو که بدونی میشه ProgressBar یا هر ایده ی دیگه ای برا راضی نگه داشتن کاربر در حین ایجاد thumbnailها پیاده سازی کنی.


سلام ممنون از راهنماییت
خودمم دقیقا به همین فکر کرده بودم ولی به این دلیل ازش استفاده نکردم چون وقتی مثلا 200 تا عکس رو میخواستم باهاش همچین کاری بکنم 50 ثانیه طول میکشید
برنامه هم تحت شبکه هست و توی شبکه خیلی بیشتر طول میکشه
ولی متاسفانه هرچی گشتم راه حل مناسبی پیدا نکردم واسه همین مجبور شدم یه برنامه بنویسم که هرچی عکس توی سرور هست ازش یک thumbnail بسازه که هرموقع پرونده ای رو خواستم لود کنم از فایل های thumb استفاده کنه و موقعی که روش کلیک میکنن فایل اصلی رو توی pictureBox نشون بده

توی سرور 500 هزارتا عکس هست
باید از همش یه thumb بسازم و به برنامه اصلی یه کد اضافه کنم که هرعکسی که اسکن کردیم باهاش ازش یه thumb بسازه واسه وقتی پرونده ها میخواد مرور بشه

با فایل های thumb فقط 1 ثانیه طول کشید تا 200 تا عکس لود بشه بدون مشکل ram :لبخندساده: