簡體   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