문제

내 C#(3.5)응용 프로그램을 위해 평균 색상 값에 대해 적색,녹색,청색 채널의 비트맵.바람직하게 사용하지 않고 외부 라이브러리입니다.할 수 있습니까?그렇다면,어떻게 합니까?미리 감사드립니다.

만들려고 하는 것을 조금 더 정확:각 픽셀 비트맵에서는 특정 RGB 색상 값입니다.을 얻고 싶은 평균 RGB 값에 대한 모든 픽셀은 이미지입니다.

도움이 되었습니까?

해결책

는 가장 빠른 방법은 사용하여 안전하지 않은 코드:

BitmapData srcData = bm.LockBits(
            new Rectangle(0, 0, bm.Width, bm.Height), 
            ImageLockMode.ReadOnly, 
            PixelFormat.Format32bppArgb);

int stride = srcData.Stride;

IntPtr Scan0 = srcData.Scan0;

long[] totals = new long[] {0,0,0};

int width = bm.Width;
int height = bm.Height;

unsafe
{
  byte* p = (byte*) (void*) Scan0;

  for (int y = 0; y < height; y++)
  {
    for (int x = 0; x < width; x++)
    {
      for (int color = 0; color < 3; color++)
      {
        int idx = (y*stride) + x*4 + color;

        totals[color] += p[idx];
      }
    }
  }
}

int avgB = totals[0] / (width*height);
int avgG = totals[1] / (width*height);
int avgR = totals[2] / (width*height);

주의:지 않았 이 코드를 테스트...(저도 몇몇 비용을 절감)

또한 이 코드는 asssumes32 비트 이미지입니다.24-bit 이미지입니다.변경 x*4 하기 x*3

다른 팁

여기에는 훨씬 더 간단한 방법:

Bitmap bmp = new Bitmap(1, 1);
Bitmap orig = (Bitmap)Bitmap.FromFile("path");
using (Graphics g = Graphics.FromImage(bmp))
{
    // updated: the Interpolation mode needs to be set to 
    // HighQualityBilinear or HighQualityBicubic or this method
    // doesn't work at all.  With either setting, the results are
    // slightly different from the averaging method.
    g.InterpolationMode = InterpolationMode.HighQualityBicubic;
    g.DrawImage(orig, new Rectangle(0, 0, 1, 1));
}
Color pixel = bmp.GetPixel(0, 0);
// pixel will contain average values for entire orig Bitmap
byte avgR = pixel.R; // etc.

기본적으로,당신은 사용 DrawImage 를 복사본을 비트맵으로 1 픽셀 Bitmap.의 RGB 값을 1 픽셀을 나타내고 평균 전체에 대한 원래 있습니다.GetPixel 은 상대적으로 느리고,하지만 당신이 그것을 사용할 때에 큰 비트맵 픽셀.전화 번 여기에 아냐.

사용 LockBits 은 참으로 빠른하지만,일부 윈도우 사용자가 보안을 금지하는 정책을 실행하지 않는 코드입니다.내가 이것을 언급하기 때문에 이 사실을 그냥 조금 나에서 뒤였습니다.

업데이트:와 InterpolationMode 설정 HighQualityBicubic,이 방법 대으로 평균 가 LockBits;와 HighQualityBilinear,그것은 약간만 이상 LockBits.그렇지 않으면 사용자가 보안을 금지하는 정책 unsafe 코드를 확실히 사용하지 않는 내 방법입니다.

Update2: 시간의 흐름과 함께,내가 지금 왜 이 방법을 작동하지 않는다.심지어 가장 높은 품질 보간 알고리즘을 통합하는 몇 주변 픽셀,그래서 거의 제한이 얼마나 많은 이미지할 수 있습 숙청을 잃지 않고 아래로 정보입니다.과 밀어 붙이는 이미지를 아래로 하나의 픽셀은 잘 넘어 이 제한은,어떠한 알고리즘을 사용 합니다.

은 작업을 수행할 수 있는 유일한 방법이 될 것이 축소에 이미지 단계를(아마도 축소 반으로 각각 시간)을 얻을 때까지 그것의 크기는 한 픽셀.수 익스프레스에 단순한 말로 완전한 시간의 낭비가 작성이 같은 것,그래서 나는 중지된 때 나는 나 자신의 생각했습니다.:)

십시오,아무도 투표에 대한 이 대답은 더 이상 그것이 될 수 있습니다 멍청한 아이디어이다.

이 종류의 것은 작동하지만 그것은 되지 않을 수 있습니다 충분히 빠르다는 것이 유용합니다.

public static Color getDominantColor(Bitmap bmp)
{

       //Used for tally
       int r = 0;
       int g = 0;
       int b = 0;

     int total = 0;

     for (int x = 0; x < bmp.Width; x++)
     {
          for (int y = 0; y < bmp.Height; y++)
          {
               Color clr = bmp.GetPixel(x, y);

               r += clr.R;
               g += clr.G;
               b += clr.B;

               total++;
          }
     }

     //Calculate average
     r /= total;
     g /= total;
     b /= total;

     return Color.FromArgb(r, g, b);
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top