سؤال

لدي مشكلة في الذاكرة عندما أحاول تحميل بعض الصور في صورة واحدة.

public void button2_Click(object sender, EventArgs e)
    {


        FolderBrowserDialog dialog = new FolderBrowserDialog();
        dialog.ShowDialog();
        string selected = dialog.SelectedPath;

        string[] imageFileList = Directory.GetFiles(selected);


        int iCtr = 0,zCtr = 0;
        foreach(string imageFile in imageFileList)
        {

            if (Image.FromFile(imageFile) != null)
            {
                Image.FromFile(imageFile).Dispose();
            }

            PictureBox eachPictureBox = new PictureBox();

            eachPictureBox.Size = new Size(100,100);
           // if (iCtr % 8 == 0)
            //{
             //   zCtr++;
              //  iCtr = 0;
            //}
            eachPictureBox.Location = new Point(iCtr * 100 + 1, 1);
            eachPictureBox.Image = Image.FromFile(imageFile);
            iCtr++;

            panel1.Controls.Add(eachPictureBox);

        }


    }`enter code here`
هل كانت مفيدة؟

المحلول

if (Image.FromFile(imageFile) != null)
{
    Image.FromFile(imageFile).Dispose();
}

سيئ. أنت تقوم بتحميل الصورة من الملف، والتحقق لمعرفة ما إذا كانت النتيجة خالية ... ثم قم بتحميلها مرة أخرى إلى نتيجة جديدة حتى تتمكن من التخلص منها. في حين أن الجزء الأخير هو سخيف، فإنه ليس ضارا. الجزء الأول هو، كما هو الناتج Image لا يتم التخلص منها بشكل صحيح من (إذا / عندما يجمعه GC، والهذه Image يكتب ينبغي تخلص من الموارد غير المدارة، لكن هذا ليس شيئا حكيما يجب الاعتماد عليه).

صدفة، Image.FromFile لن يعود أبدا null. وبعد إذا لم يتمكن من قراءة الصورة، فسيتم رمي OutOfMemoryException.

كما يبدو الرمز لا يفعل شيئا، لأنه لا يوجد else كتلة ولا شيء يتم معنى في if منع.

تخميني هو أن الخاص بك OutOfMemoryException يأتي من حقيقة أن واحد أو أكثر من الملفات في هذا الدليل يتم تخزينه بتنسيق صورة تالفة أو غير مدعوم, ، أو ليست صورة على الإطلاق.

حاول استبدال الرمز في foreach مع هذا:

try
{
    Image image = Image.FromFile(imageFile);

    PictureBox eachPictureBox = new PictureBox();

    eachPictureBox.Size = new Size(100,100);

    eachPictureBox.Location = new Point(iCtr * 100 + 1, 1);
    eachPictureBox.Image = Image.FromFile(imageFile);
    iCtr++;

    panel1.Controls.Add(eachPictureBox);
}
catch(OutOfMemoryException) { } // skip the file

نصائح أخرى

يحمل مربع الصورة داخليا مرجعا إلى الصورة النقطية التي تضعها فيها. ما لم تتخلص من المربع صورة، فإنه يحمل إشارة إلى كل صورة نقطية تقوم بتحميلها فيها.

شيء يجب أن تفكر فيه بغض النظر عن نوع الصورة المخزنة على القرص، عند فتحه لعرض الصورة، ستصبح الصورة نقطية وتتطلب 4 بايت لكل بكسل المعروض.

يبدو أن الكود الخاص بك يقترح محاولة في عملية مصغرة. أنت في الواقع تحميل 70 ملف في الذاكرة وبغض النظر عن حجم الشاشة، في الذاكرة، سيكونون كبيرا جدا.

على سبيل المثال، دعنا نقول أن لديك 70 jpegs في عمق اللون 32 بت ويقول بحجم 1920 × 1080 بكسل. شرط الذاكرة الخاصة بك لتحميل أن العديد من الصور في وقت واحد ثم هي:

 70 pics x 1920 pixels x 1080 pixels x 4 bytes/pixel = 580,608,000 bytes! 

وهذا تقدير منخفض إلى حد ما.

يمكنك التفكير في تحميل العديد من الصور أو المحاولة للحل المصغرة الحقيقية.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top