首页 > 解决方案 > 如何通过此功能使用更少的内存?

问题描述

我正在从大约 70,000 张图像中提取信息,并希望获得它们的平均 RGB 信息。下面的当前代码有效,但内存不足。到目前为止,它只打印出相机品牌、型号、RGB 值和文件名。首先,我找到了我改编的这段代码:

    public static RGBValues AverageRGB(Bitmap bm)
    {
        BitmapData srcData = bm.LockBits(
            new System.Drawing.Rectangle(0, 0, bm.Width, bm.Height),
            ImageLockMode.ReadOnly,
            System.Drawing.Imaging.PixelFormat.Format32bppArgb);

        int stride = srcData.Stride;

        IntPtr Scan0 = srcData.Scan0;

        long[] totals = new long[] { 0, 0, 0 };

        int width = bm.Width;
        int height = bm.Height;

        unsafe
        {
            byte* p = (byte*)(void*)Scan0;

            for (int y = 0; y < height; y++)
            {
                for (int x = 0; x < width; x++)
                {
                    for (int color = 0; color < 3; color++)
                    {
                        int idx = (y * stride) + x * 4 + color;

                        totals[color] += p[idx];
                    }
                }
            }
        }

        long avgB = totals[0] / (width * height);
        long avgG = totals[1] / (width * height);
        long avgR = totals[2] / (width * height);
        RGBValues rgb = new RGBValues();
        rgb.R = avgR;
        rgb.G = avgG;
        rgb.B = avgB;
        return rgb;
    }

    public class RGBValues
    {
        public long R;
        public long G;
        public long B;
    }

然后我这样称呼它:

    public MainWindow()
    {
        string folder = @"F:\Photos";
        DirSearch(folder);
        int counter = 0;
        foreach (var filename in filelist)
        {
            GetImageInfo(filename);
            counter++;
            if (counter >= 10)
            {
                GC.Collect();
                GC.WaitForPendingFinalizers();
                counter = 0;
            }
        }

        InitializeComponent();
    }
    private void GetImageInfo(string filename)
    {
        FileInfo info = new FileInfo(filename);

        System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
        Bitmap bmp = new Bitmap(filename);
        PropertyItem[] propItems = bmp.PropertyItems;
        var temp = AverageRGB(bmp);
        string manufacturer = encoding.GetString(propItems[1].Value);
        string model = encoding.GetString(propItems[2].Value);
        Console.WriteLine("manufacturer: " + manufacturer + ", model: " + model + ", colorinfo: " + temp.R + ", " + temp.G + ", " + temp.B + ", Filename: " + info.Name);
    }
    public static void DirSearch(string sDir)
    {
        try
        {
            foreach (string d in Directory.GetDirectories(sDir))
            {
                foreach (string f in Directory.GetFiles(d))
                {
                    filelist.Add(f);
                }
                DirSearch(d);
            }
        }
        catch (System.Exception excpt)
        {
            Console.WriteLine(excpt.Message);
        }
    }

我投入了一些垃圾收集工作,但在拍摄了大约 150 张照片后,它仍然内存不足。我认为 C# 会自动丢弃它不再需要的信息。是因为它正在使用unsafe它继续保留额外的信息吗?我能做些什么来强制它清除旧信息?

标签: c#image-processingunsafe

解决方案


推荐阅读