c#中是否有处理高分辨率照片的有效方法?

本文关键字:有效 方法 照片 高分辨率 是否 处理 | 更新日期: 2023-09-27 18:06:46

我编写了一个程序,分析图像的第一个像素,然后在List中记录它的值,这是为了检查图像是黑白的还是彩色的。现在,有人知道一种读取高分辨率图像的有效方法吗?现在我使用的是位图,但它们效率非常低。每张图像大约有1800万像素,我想分析大约400张照片。下列代码:

Bitmap b;
foreach (FileInfo f in files) {
  // HUGE MEMORY LEAK
  System.GC.Collect();
  System.GC.WaitForPendingFinalizers();
  b = (Bitmap)Bitmap.FromFile(f.FullName);
  // reading pixel (0,0) from bitmap

当我运行程序时,它说:

"An unhandled exception of type 'System.OutOfMemoryException' occurred in System.Drawing.dll
Additional information: There is no available memory."

我已经尝试用System.GC.Collect()来清理,正如你所看到的,但是异常并没有消失。如果我分析一个文件夹,其中只包含几张照片,程序运行良好,并愉快地完成它的工作。

c#中是否有处理高分辨率照片的有效方法?

使用图像的第一个像素来检查它是否是彩色的,这是错误的方法。

如果你有一个黑色背景的图像(像素值在RGB中为0,0,0),你怎么知道这个图像是黑白的,而不是黑色背景的颜色?

将位图放置在Using中是正确的,因为它将正确地处理。

下面的代码就可以了。

class Program
{
    static void Main(string[] args) {
        List<String> ImageExtensions = new List<string> { ".JPG", ".JPE", ".BMP", ".GIF", ".PNG" };
        String rootDir = "C:''Images";
        foreach (String fileName in Directory.EnumerateFiles(rootDir)) {
            if (ImageExtensions.Contains(Path.GetExtension(fileName).ToUpper())) {
                try {
                    //Image.FromFile will work just as well here.
                    using (Image i = Bitmap.FromFile(fileName)) {
                        if (i.PixelFormat == PixelFormat.Format16bppGrayScale) {
                            //Grey scale...
                        } else if (i.PixelFormat == PixelFormat.Format1bppIndexed) {
                            //1bit colour (possibly b/w, but could be other indexed colours)
                        }
                    }
                } catch (Exception e) {
                    Console.WriteLine("Error - " + e.Message);
                }
            }
        }
    }
}

在这里找到PixelFormat的参考- https://msdn.microsoft.com/en-us/library/system.drawing.imaging.pixelformat%28v=vs.110%29.aspx

c#中的

对象限制为2Gb,所以我怀疑单个图像会导致问题。我还建议您永远不要手动调用GC来解决内存泄漏(尽管这不是技术上的泄漏,只是内存占用过多)。

使用语句对于确保对象被标记为要处理是完美的,并且GC非常擅长清理。

我们在软件中执行密集的图像处理,并且使用我所展示的方法从未出现过内存问题。

虽然简单地读取头来查找图像数据是一个完全正确的解决方案,但它确实意味着大量额外的工作来解码不同的文件类型,这是没有必要的,除非你在非常小的内存中处理大量的图像(尽管如果这是你的目标,直接C是比c#更好的方法。马的课程和所有的爵士乐!)

EDIT -我刚刚在一个包含超过5000个高分辨率tiff的目录上运行了这个,没有内存问题。这个过程中最慢的部分是控制台输出!

我猜,如果你只需要第一个像素-没有必要读取所有文件。也许你应该从位图字节数组中取第一个像素,然后处理它。你应该手动找到像素数组并先取。

如何找到像素数组?嗯,这取决于文件格式。您应该找到每种可用格式的规范并使用它。下面是BMP阅读器

的示例