【解決方法】ソースフォルダーから画像を継続的に読み込むにはどうすればよいですか?


私のプログラムは次のステップで構成されています。
1. ソースフォルダーから新しい画像を読み込みます。
2. 画像の処理 (オブジェクトの検出と傾き補正)
3. デスキューしたオブジェクト画像をターゲットフォルダーに保存します
…繰り返す

このアイデアは、スタンプをスキャンするときにプログラムが各スタンプを個別に出力するか、スタンプがクラスター化されている場合はグループ化して出力するというものです。 ユーザーは、スキャンの処理中に継続的にスキャンを実行できる必要があります。

このプログラムは、ターゲット フォルダー内の新しい画像を検出する 3 つの方法に基づいて、3 つの異なる方法で動作します。 実際には 3 番目の方法のみが使用されます。 最初の 2 つは、何が起こっているのか、そしてその理由を説明するのに役立つことを願っています。

1. ドラッグアンドドロップ
画像をフォルダーに手動でドラッグ アンド ドロップすると、すべて正常に動作します。 これは無制限に実行でき、出力は正確です。

2.コピペ
画像をローカルのターゲット フォルダーにコピーして貼り付けると、プログラムがすぐに停止し、次の例外が表示されます。

System.IO.IOException: 'Unable to access the file xxx because it is being used by another process.'

ターゲットフォルダー内の画像をコピー&ペーストするときにも、これと同じ例外が発生します。

3. スキャンプログラムからの出力
ScanSnap SV600を使用していますが、スキャンしたスタンプを未処理の状態で対象フォルダーに保存します。 さて、ここで私を困惑させるケースが発生します。つまり、私の処理プログラムの動作が交互になります。 デバッグ モードでプログラムを起動するたびに、最初のスキャンは常に成功します。 ただし、前のデバッグ セッションが成功した場合、処理プログラムの同じ実行内での後続のスキャンでの読み取りは失敗します。 言い換えれば、プログラムは 2 回に 1 回、希望どおりに動作します。 また、2 回目のスキャンで停止し、上記のエラーが表示される場合もあります。

新しい画像を検出するには以下を使用します。

C#
var fileSystemWatcher = new FileSystemWatcher(@inputDir)
{
    Filter = "*.jpg",
    NotifyFilter = NotifyFilters.FileName | NotifyFilters.LastWrite,
    EnableRaisingEvents = true
};
fileSystemWatcher.Created += new FileSystemEventHandler(OnFileCreated);

私が試したこと:

さらに、これは処理が開始される前のコードの一部です。 これは最も美しいものではなく、「Thread.Sleep()」を使用するのは少し「荒っぽい」ように感じます。 もしかしたらここにヒントがあるかも?

C#
private void OnFileCreated(object sender, FileSystemEventArgs e)
{
    sw.Restart();
    string imagePath = e.FullPath;
    inputFiles.AddToQ(imagePath);
    Console.WriteLine("{0} is queued.", e.FullPath);

    int number = 0;
    if (!int.TryParse(setCluster.Text.Trim(), out number))
    {
        MessageBox.Show("Please enter a valid number for Clustering.");
        setCluster.Text = "20";
    }
    else
    {
        while (inputFiles.Inspect() != imagePath) Thread.Sleep(100);
        try
        {
            lock (locker)
            {
                Bitmap incoming = new Bitmap(inputFiles.Process());
                Console.WriteLine("{0} is being processed.", e.FullPath);

                if (currentScan.Image != null) currentScan.Image = null;
                currentScan.Invoke((Action)
                delegate ()
                {
                    currentScan.Image = (Image)new Bitmap(e.FullPath);
                    currPathText.Text = imagePath;
                });

                // processing step
                Bitmap resized = new Bitmap(incoming, new
                    Size(Convert.ToInt32(incoming.Width / Variables.ScalingFact),
                    Convert.ToInt32(incoming.Height / Variables.ScalingFact)));
                .....

解決策 1

これは簡単です。 コピープロセスが完了してファイルを閉じる前にファイルを読み取ろうとしています。

ファイルを開いてみるだけです。 すでに使用されているために例外がスローされた場合は、少し待ってから再試行してください。 ファイルを開くか、任意に選択した再試行制限を使い果たすまで、試行を続けてください。

コメント

タイトルとURLをコピーしました