簡體   English   中英

C#中處理大量圖像文件的最快或最有效方法

[英]fastest or most efficient way to process large number of image files in c#

我必須閱讀並找出存儲在我們網絡中的大約450,000個圖像文件的壓縮類型。 這是我到目前為止所能得到的,並且可以按需要工作,但是我觀察到的是每小時處理2000個文件。 速度較慢的原因之一可能是因為文件是從共享的網絡位置讀取的,但目前尚無解決方法。

任何建議將不勝感激。

using System;
using System.Configuration;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Imaging;
using System.Globalization;
using System.Data;
using System.IO;
using FileHelpers;
using System.Threading.Tasks;

namespace CompressionTypeOfEDMSTiffs
{
    public static class ImageProcessor
    {
        private static readonly object lockObject = new object();

        public static void Process()
        {
            string docNumber = "";
            try
            {
                Stopwatch _stopwatch = new Stopwatch();

                _stopwatch.Start();

                var filename = ConfigurationManager.AppSettings["filePath"].Trim();

                var dtCsv = CsvEngine.CsvToDataTable(filename, ',');

                dtCsv.Columns.Add("CompressionType");
                dtCsv.Columns["CompressionType"].SetOrdinal(dtCsv.Columns.Count - 1);

                //One-by one
                //for (var rowNum = 0; rowNum < dtCsv.Rows.Count; rowNum++)
                //{
                //    var imgPath = dtCsv.Rows[rowNum]["Path"].ToString();

                //    if (!string.IsNullOrWhiteSpace(imgPath) && imgPath.LastIndexOf(".") != -1)
                //    {
                //        if (imgPath.Substring(imgPath.LastIndexOf(".")).ToUpper().Equals(".TIF"))
                //        {
                //            docNumber = dtCsv.Rows[rowNum]["DOCNUMBER"].ToString();

                //            var compression = GetCompressionTypeFromImage(imgPath);

                //            dtCsv.Rows[rowNum]["CompressionType"] = compression;

                //            //if (Enum.IsDefined(typeof(CompressionTypes), compression))
                //            //    dtCsv.Rows[rowNum]["CompressionType"] = compression.ToString();
                //            //else
                //            //{
                //            //    dtCsv.Rows[rowNum]["CompressionType"] = "UnRecognised";
                //            //}

                //            Console.WriteLine(string.Format("Counter = {0}, docnumber = {1} , path = {2},  CT = {3}", rowNum, docNumber, imgPath, compression));
                //        }
                //    }
                //}

                //Multi-tasking
                Parallel.ForEach(dtCsv.AsEnumerable(), drow =>
                {
                    var imgPath = drow["Path"].ToString();

                    if (!string.IsNullOrWhiteSpace(imgPath) && imgPath.LastIndexOf(".") != -1)
                    {
                        if (imgPath.Substring(imgPath.LastIndexOf(".")).ToUpper().Equals(".TIF"))
                        {
                            docNumber = drow["DOCNUMBER"].ToString();

                            var compression = GetCompressionTypeFromImage(imgPath);

                            drow["CompressionType"] = compression;

                            Console.WriteLine(string.Format("docnumber = {0} , path = {1},  CT = {2}", docNumber, imgPath, compression));
                        }
                    }
                });

                if (File.Exists(filename))
                    File.Delete(filename);

                //write CSV
                var tempTable = dtCsv.Copy();
                var headerRow = tempTable.NewRow();

                foreach (DataColumn col in dtCsv.Columns)
                    headerRow[col.ColumnName] = col.ColumnName;

                headerRow[headerRow.ItemArray.Length - 1] = "CompressionType";

                tempTable.Rows.InsertAt(headerRow, 0);

                CsvEngine.DataTableToCsv(tempTable, ConfigurationManager.AppSettings["filePath"].Trim());

                _stopwatch.Stop();

                Console.WriteLine(string.Format("Time elapsed in the process {0} minutes", _stopwatch.Elapsed.TotalMinutes.ToString("#.##")));

                Console.ReadLine();
            }
            catch (Exception exception)
            {
                Console.WriteLine(!string.IsNullOrWhiteSpace(docNumber)
                                      ? string.Format("Error in document No {0} and the error is {1} stack trace {2}",
                                                      docNumber, exception.Message, exception.StackTrace)
                                      : string.Format("Error is {0} stack trace {1}", exception.Message,
                                                      exception.StackTrace));
                Console.ReadLine();
            }
        }


        private static string GetCompressionTypeFromImage(string path)
        {
            string compression = "";
            try
            {
                lock (lockObject)
                {
                    using (var fs = new FileStream(path, FileMode.Open, FileAccess.Read))
                    {
                        using (Image sourceImage = Image.FromStream(fs))
                        {
                            var compressionTagIndex = Array.IndexOf(sourceImage.PropertyIdList, 0x103);
                            PropertyItem compressionTag = sourceImage.PropertyItems[compressionTagIndex];

                            var compressionType = (CompressionTypes)Enum.Parse(typeof(CompressionTypes),
                                                            BitConverter.ToInt16(compressionTag.Value, 0).ToString(CultureInfo.InvariantCulture));

                            if (Enum.IsDefined(typeof(CompressionTypes), compressionType))
                                compression = compressionType.ToString();
                            else
                            {
                                compression = "UnRecognised";
                            }
                        }
                    } 
                }
            }
            catch (Exception exFileStream)
            {
                compression = exFileStream.Message;
            }

            return compression;
            //using (var sourceImage = Image.FromFile(path))
            //{
            //    var compressionTagIndex = Array.IndexOf(sourceImage.PropertyIdList, 0x103);
            //    PropertyItem compressionTag = sourceImage.PropertyItems[compressionTagIndex];
            //    return (CompressionTypes)Enum.Parse(typeof(CompressionTypes), BitConverter.ToInt16(compressionTag.Value, 0).ToString(CultureInfo.InvariantCulture));
            //}
        }
    }

    public enum CompressionTypes
    {
        NoCompression = 1,
        CcittGroup3 = 2,
        FacsimilecompatibleCcittGroup3 = 3,
        CcittGroup4 = 4,
        Lzw = 5,
        UnRecognised = 6,
        ExceptionInFilehandling = 7
    }
}

您可以在承載文件的服務器上運行程序,而不是通過網絡讀取文件嗎?

如果沒有,我將有一個程序將文件從網絡復制到本地文件夾以充當隊列。 然后讓第二個程序從本地隊列文件夾中讀取圖像,確定壓縮率,然后刪除該文件。 這樣可以將網絡IO時間與文件處理時間分開。

這些是我想到的幾件事:

  1. Parallel.For而不是for瀏覽列表。
  2. 安裝了異步CTP的.net 4.5或.net 4中的async / await。 主題太廣泛,無法在此處進行討論。 您可以此處查看“ 異步/等待”
  3. TPL DataFlow還可以幫助並行化流程。

您不是在描述問題或問題。 在這個社區中這是不可接受的。 嘗試編輯您的問題,並更精確地解決您的問題以及您想做什么。

如果瓶頸是CPU,請嘗試一次在多個線程中進行工作。

如果瓶頸是文件訪問,則可以將圖像移動到SSD驅動器或內存驅動器中,然后從那里訪問它們。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM