2012-10-02 9 views
6

私はどこにでも見ましたが、イメージが空白であるかどうかをチェックする方法の標準(私が見ることができる)はありません。 C#でCでイメージが空白かどうかを確認する#

私はこれを行う方法がありますが、正しい方法は、画像が空白であるかどうかを確認することが大好きですので、誰もが将来知っていることができます。

コードのコピーを貼り付けるつもりはありません。私が欲しいのであれば、私の喜びになりますが、最初に画像が空白かどうかをチェックする方法について説明したいと思います。

あなたは.jpg画像を撮影し、その幅を取得します。例えば500個のピクセル は、次に、2 はあなた

250を与えることによって、あなたはすべてのピクセルの色がの位置にあるかどうか確認する(250幅、及びI高さ)は、反復(のハイトを考えていること分割します画像。

これは、画像のピクセルの中央のラインを垂直方向にチェックすることです。色が何かであるかどうかをすべてのピクセルでチェックしていますが、白以外のものはありません。すべての500 *ピクセルの高さを検索すると、ほとんどの場合、ページの中央に色が表示されます。

その作業...少し遅いです...これを行うより良い方法は? 2/3/4行を垂直方向に検索するように変更すると、空白ではないページを見つける機会が増えますが、それ以上の時間がかかります。

(2つの上の文章や空白のページのサイズとページがお互いに近すぎるため、また、それは何かが、この場合には動作しません含まれているかどうかをチェックするために画像のサイズを使用して、注意してください) 溶液を加えた後。

ソリューションの実装と理解を支援するリソース。

  • Using Pointers in C#
  • (最初のウェブサイト上でなお、述べPizelformatは実際にはピクセルフォーマットである) - 小さな誤差は私が知っている、ちょうど言及、かもしれませんいくつかの人にいくつかの混乱を引き起こします。

    ピクセルハンティングを高速化する方法を実装した後、速度はそれほど向上しませんでした。だから私は何か間違っていると思うだろう。

    40画像では旧式= 15.63です。

    新しい時間= 40枚の画像

    のための15.43私はピクセルの集合内のコード「ロック」という、素晴らしい記事DocMax quotedで見ました。 (または私がそれをどのように理解したか) 私がしたことは、各ページの中央のピクセル行にロックされていることです。それが正しい動きだろうか?あなたはそれが間違って得ることのチャンスを許容できる場合

    private int testPixels(String sourceDir) 
        { 
         //iterate through images 
         string[] fileEntries = Directory.GetFiles(sourceDir).Where(x => x.Contains("JPG")).ToArray(); 
    
         var q = from string x in Directory.GetFiles(sourceDir) 
           where x.ToLower().EndsWith(".jpg") 
           select new FileInfo(x); 
    
         int holder = 1; 
         foreach (var z in q) 
         { 
          Bitmap mybm= Bitmap.FromFile(z.FullName) as Bitmap; 
          int blank = getPixelData2(mybm); 
    
          if (blank == 0) 
          { 
           holder = 0; 
           break; 
          } 
         } 
         return holder; 
        } 
    

    そしてクラス

    private unsafe int getPixelData2(Bitmap bm) 
         { 
          BitmapData bmd = bm.LockBits(new System.Drawing.Rectangle((bm.Width/2), 0, 1, bm.Height), System.Drawing.Imaging.ImageLockMode.ReadOnly, bm.PixelFormat); 
    
          int blue; 
          int green; 
          int red; 
    
          int width = bmd.Width/2; 
          for (int y = 0; y < bmd.Height; y++) 
          { 
           byte* row = (byte*)bmd.Scan0 + (y * bmd.Stride); 
    
           blue = row[width * 3]; 
           green = row[width * 2]; 
           red = row[width * 1]; 
    
           // Console.WriteLine("Blue= " + blue + " Green= " + green + " Red= " + red); 
           //Check to see if there is some form of color 
           if ((blue != 255) || (green != 255) || (red != 255)) 
           { 
            bm.Dispose(); 
            return 1; 
           } 
          } 
          bm.Dispose(); 
          return 0; 
         } 
    
    +0

    時間がかかりましたか?もしそうなら、時間は何でしたか?画像の高さは? – 3aw5TZetdf

    +1

    あなたのアルゴリズムは私のように思えるので、実装に何か間違っていなければなりません。ビットマップの1つの列をスキャンするのに時間がかかりません。 –

    +0

    32画像の合計時間= 00:00:12.9187389 高さ= 6552 幅= 4580 – Ruan

    答えて

    7

    を、アプローチは罰金です。私はエラーに対処するための視覚的な確認が常にあったが、私の場合は非常に似たようなことをしてきた。

    パフォーマンスについては、どのようにピクセルをテストするかが重要です。 Bitmap.GetPixelを使用している場合は、パフォーマンスに問題があります。

    すべてのピクセルを一度に取得してループオーバーすると、パフォーマンスが向上します。これは、Googleの「Bitmap.GetPixel slow」で検索してください。私は個人的には、明確さと完全性のためにBob Powell's LockBits discussionが好きです。このアプローチでは、すべてのピクセルをチェックすることは、パフォーマンスのニーズに応じて適切かもしれません。

    +0

    実際には、Bitmap.GetPixelを使用しています。 ありがとう、病気その解決策をチェックし、ここに私の調査結果を掲示してください。一つの完全な解決策があり、イメージをチェックする方法についての標準を敢えて言ってください。 – Ruan

    +0

    だから私は解決策を実装しました。唯一のことは、時間はほぼ同じです古い画像= 40枚の画像では15.63枚です。そして、新しい時間は= 40画像40 = 15.43です。私が行ったことの上で私の質問に関する追加情報として説明してください。 – Ruan

    +0

    それは分数でそれをスピードアップします。私はデータの量が増えているのを見るのが難しいと思う。 ありがとうございました – Ruan

    2

    あなたがSystem.Drawing.Bitmapを使用している場合は、(実質的に)物事をスピードアップすることができ、によって:

    1. ピクセルにアクセスするにはgetPixelとを使用していない、に画像ビットマップをコピーするためにするLockBitsとUnLockBitsをを使用定期的な記憶。使用方法については、MSDN documentationの例を参照してください。
    2. forループのWidth、Height、またはSizeプロパティを呼び出さない。 Call Sizeを一度呼び出すと、ローカル変数に値を格納し、ループ内の値を使用します。

    注:

    1. デバイスメモリであってもよいSystem.Drawing.Bitmapあなたのイメージを使用して、それは時間がかかるかもしれアクセスします。
    2. イメージをビットマップにロードすると、既に他のフォーマットが使用するのが難しいため、イメージをRGBフォーマットに変換しているかどうかはわかりませんが、そうでない場合は、RGBビットマップを同じサイズGraphicsImageを使用し、DrawImageを使用して元のイメージをRGBビットマップに描画します。

    編集:DocMaxによるパンチに勝つ。

    いずれの場合でも、C#ラッパーを含む優れたFreeImageなどの代替ライブラリを使用することもできます。

    0

    スケールの1x1の画像は、次に、一つの画素

    新しいビットマップチェック(previousImage、新しいサイズ(1、1))。

    +0

    これは素晴らしいですが、残念ながら、私が試したほとんどの画像(argbカラー値を持つ64x56タイルのセット)ではうまくいきません。ソースに何らかのイメージデータが含まれている場合でも、単一のピクセルは頻繁に0,0,0,0です。 – PeteB

    +0

    私は2x2を使ってさらに4つのピクセルをすべて検査しました。それはタイルに少量の内容があったときにはより良いものの、まだ空であると報告されました。 – PeteB

    関連する問題