繁体   English   中英

有没有一种有效的方法来处理C#中的高分辨率照片?

[英]Is there an efficient way of handling high-res photos in C#?

我已经制作了一个程序,可以分析图像的第一个像素,然后在列表中记录其值,以检查图像是黑白还是彩色。 现在,有人知道读取高分辨率图像的有效方法吗? 现在我正在使用位图,但是它们的效率很低。 每个图像大约18兆像素,我想分析大约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()进行清理,但是异常不会消失。 如果我分析一个仅包含几张照片的文件夹,则该程序可以正常运行,并且很高兴可以完成此工作。

使用图像的第一个像素检查其是否为彩色是错误的方法。

如果您有黑色背景的图像(RGB中的像素值为0,0,0),您如何知道该图像是黑白的,而不是黑色背景的?

将位图放置在“使用中”是正确的,因为它将正确处理。

以下将解决问题。

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是一种更好的实现方式。

编辑-我只是在包含5000多个高分辨率TIFF的目录上运行了此文件,而没有内存问题。 这个过程中最慢的部分是控制台输出!

我想,如果您只需要第一个像素-不需要读取所有文件。 也许您应该只从位图字节数组中提取第一个像素并对其进行处理。 您应该手动找到像素阵列,然后再进行拍摄。

如何找到像素阵列? 好吧,这取决于文件格式。 您应该找到每种可用格式的规范并使用它。 这是BMP阅读器的示例

我认为您可以通过布置位图来解决问题。

尝试这个:

     foreach (var f in files)
     {
        using (Bitmap b = (Bitmap)Image.FromFile(f))
        {
           //Do some work
        }
     }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM