2012-04-26 10 views
3

画像が色付きであるかどうかを調べようとしています。 this StackOverflowの質問では、のPixelFormat列挙型をチェックする必要があるとの回答があります。残念ながら、返信は私にはあまり明確ではありません。 image.PixelFormatPixelFormat.Format16bppGrayScaleと異なっているかどうかを確認するのは安全ですか?列挙の他の値はどうでしょうか? MSDNのドキュメントはあまり明確ではありません...画像が色付きであるかどうかを確認

+0

色をサポートしているか、色が入っているかどうか確認しますか?これはFormat32bppArgbでもかまいませんが、依然として黒、白、灰色のみです。 – SimpleVar

+0

@ YoryeNathan:色が入っているかどうかを知りたい。 – Kassem

+0

これは別のことです。すべてのPixelFormatで機能しますか? – SimpleVar

答えて

11

これを改善するには、Color.FromArgbを避け、intの代わりにバイトを繰り返しますが、これは読みやすく、理解しやすいと思っていました。アプローチ。

一般的な考え方は、画像を既知の形式(32bpp ARGB)のビットマップ、 に描画し、そのビットマップに色が含まれているかどうかを確認することです。

ビットマップのビットをロックすると、安全でないコードを使用して、GetPixelを使用するよりも何倍も速く色データを繰り返し処理できます。

ピクセルのアルファが0の場合、アルファ0は完全に不透明であるため、明らかにGrayScaleです。それ以外の場合 - R = G = Bの場合は灰色です(255の場合は黒です)。

private static unsafe bool IsGrayScale(Image image) 
{ 
    using (var bmp = new Bitmap(image.Width, image.Height, PixelFormat.Format32bppArgb)) 
    { 
     using (var g = Graphics.FromImage(bmp)) 
     { 
      g.DrawImage(image, 0, 0); 
     } 

     var data = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, bmp.PixelFormat); 

     var pt = (int*)data.Scan0; 
     var res = true; 

     for (var i = 0; i < data.Height * data.Width; i++) 
     { 
      var color = Color.FromArgb(pt[i]); 

      if (color.A != 0 && (color.R != color.G || color.G != color.B)) 
      { 
       res = false; 
       break; 
      } 
     } 

     bmp.UnlockBits(data); 

     return res; 
    } 
} 
+0

魅力的なように働いた!ありがとう:) – Kassem

+0

うれしい私は助けた。私がアルファ(0または255)と混同していないことを確認してください。それ以外は滑らかになるはずです:) – SimpleVar