c# - 如何通过此功能使用更少的内存?
问题描述
我正在从大约 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
它继续保留额外的信息吗?我能做些什么来强制它清除旧信息?
解决方案
推荐阅读
- javascript - 在检查器中调试 r2d3 (R) - 无法在控制台中查看数据?
- python - Tkinter 将图标添加到自定义标题栏(覆盖)
- karma-mocha - 如何从 Karma 获取调试消息?
- azure-devops - 在 Azure Boards 中,如何防止团队更改 sprint backlog 中用户故事的优先级?
- python - 如何在tkinter的屏幕底部(左侧一个,右侧一个)打包2个按钮?
- c# - 如何在Unity中制作透明窗口?
- excel - VBA将数据从文件夹合并到Excel中的单个工作表
- amazon-web-services - AWS Fargate 容器无法访问 Internet
- xaml - 如何在 WinUI 3 中使用 Xaml 继承?
- algorithm - (end-start+1)*懒惰[treeIndex]?