/// <summary> Attenuate the specified bitmap. /// /// </summary> /// <param name="bm">Bitmap to attenuate /// </param> /// <param name="xpos">horizontal position /// </param> /// <param name="ypos">vertical position /// </param> public virtual void Attenuate(Bitmap bm, int xpos, int ypos) { // Check // Compute number of rows and columns int xrows = ypos + bm.ImageHeight; if (xrows > ImageHeight) { xrows = ImageHeight; } if (ypos > 0) { xrows -= ypos; } int xcolumns = xpos + bm.ImageWidth; if (xcolumns > ImageWidth) { xcolumns = ImageWidth; } if (xpos > 0) { xcolumns -= xpos; } if ((xrows <= 0) || (xcolumns <= 0)) { return; } // Precompute multiplier map int maxgray = bm.Grays - 1; int[] multiplier = GetMultiplier(maxgray); // Compute starting point int src = bm.RowOffset((ypos < 0) ? (-ypos) : 0) - ((xpos < 0) ? xpos : 0); int dst = RowOffset((ypos > 0) ? ypos : 0) + ((xpos > 0) ? xpos : 0); PixelReference dstPixel = CreateGPixelReference(0); // Loop over rows for (int y = 0; y < xrows; y++) { // Loop over columns dstPixel.SetOffset(dst); for (int x = 0; x < xcolumns; dstPixel.IncOffset()) { int srcpix = bm.GetByteAt(src + (x++)); // Perform pixel operation if (srcpix > 0) { if (srcpix >= maxgray) { dstPixel.SetGray(0); } else { int level = multiplier[srcpix]; dstPixel.SetBGR((dstPixel.Blue * level) >> 16, (dstPixel.Green * level) >> 16, (dstPixel.Red * level) >> 16); } } } // Next line dst += GetRowSize(); src += bm.GetRowSize(); } }