public virtual void Apply(Graphics graphics, Bitmap applyBitmap, Rectangle rect, RenderMode renderMode) { applyRect = IntersectRectangle(applyBitmap.Size, rect); if (applyRect.Width == 0 || applyRect.Height == 0) { // nothing to do return; } bbb = new BitmapBuffer(applyBitmap, applyRect); try { bbb.Lock(); for (int y = 0; y < bbb.Height; y++) { for (int x = 0; x < bbb.Width; x++) { if (parent.Contains(applyRect.Left + x, applyRect.Top + y) ^ Invert) { IteratePixel(x, y); } } } } finally { bbb.DrawTo(graphics, applyRect.Location); bbb.Dispose(); bbb = null; } }
public static void Apply(Graphics graphics, Bitmap applyBitmap, Rectangle rect, int pixelSize) { if (pixelSize <= 1 || rect.Width == 0 || rect.Height == 0) { // Nothing to do return; } if (rect.Width < pixelSize) { pixelSize = rect.Width; } if (rect.Height < pixelSize) { pixelSize = rect.Height; } using (BitmapBuffer bbbDest = new BitmapBuffer(applyBitmap, rect)) { bbbDest.Lock(); using (BitmapBuffer bbbSrc = new BitmapBuffer(applyBitmap, rect)) { bbbSrc.Lock(); List <Color> colors = new List <Color>(); int halbPixelSize = pixelSize / 2; for (int y = -halbPixelSize; y < bbbSrc.Height + halbPixelSize; y = y + pixelSize) { for (int x = -halbPixelSize; x <= bbbSrc.Width + halbPixelSize; x = x + pixelSize) { colors.Clear(); for (int yy = y; yy < y + pixelSize; yy++) { if (yy >= 0 && yy < bbbSrc.Height) { for (int xx = x; xx < x + pixelSize; xx++) { colors.Add(bbbSrc.GetColorAt(xx, yy)); } } } Color currentAvgColor = Colors.Mix(colors); for (int yy = y; yy <= y + pixelSize; yy++) { if (yy >= 0 && yy < bbbSrc.Height) { for (int xx = x; xx <= x + pixelSize; xx++) { bbbDest.SetColorAt(xx, yy, currentAvgColor); } } } } } } bbbDest.DrawTo(graphics, rect.Location); } }
public unsafe override void Apply(Graphics graphics, Bitmap applyBitmap, Rectangle rect, RenderMode renderMode) { applyRect = IntersectRectangle(applyBitmap.Size, rect); if (applyRect.Height <= 0 || applyRect.Width <= 0) { return; } int blurRadius = GetFieldValueAsInt(FieldType.BLUR_RADIUS); double previewQuality = GetFieldValueAsDouble(FieldType.PREVIEW_QUALITY); // do nothing when nothing can be done! if (blurRadius < 1) { return; } using (BitmapBuffer bbbDest = new BitmapBuffer(applyBitmap, applyRect)) { bbbDest.Lock(); using (BitmapBuffer bbbSrc = new BitmapBuffer(applyBitmap, applyRect)) { bbbSrc.Lock(); Random rand = new Random(); int r = blurRadius; int[] w = CreateGaussianBlurRow(r); int wlen = w.Length; long[] waSums = new long[wlen]; long[] wcSums = new long[wlen]; long[] aSums = new long[wlen]; long[] bSums = new long[wlen]; long[] gSums = new long[wlen]; long[] rSums = new long[wlen]; for (int y = 0; y < applyRect.Height; ++y) { long waSum = 0; long wcSum = 0; long aSum = 0; long bSum = 0; long gSum = 0; long rSum = 0; for (int wx = 0; wx < wlen; ++wx) { int srcX = wx - r; waSums[wx] = 0; wcSums[wx] = 0; aSums[wx] = 0; bSums[wx] = 0; gSums[wx] = 0; rSums[wx] = 0; if (srcX >= 0 && srcX < bbbDest.Width) { for (int wy = 0; wy < wlen; ++wy) { int srcY = y + wy - r; if (srcY >= 0 && srcY < bbbDest.Height) { int[] colors = bbbSrc.GetColorArrayAt(srcX, srcY); int wp = w[wy]; waSums[wx] += wp; wp *= colors[0] + (colors[0] >> 7); wcSums[wx] += wp; wp >>= 8; aSums[wx] += wp * colors[0]; bSums[wx] += wp * colors[3]; gSums[wx] += wp * colors[2]; rSums[wx] += wp * colors[1]; } } int wwx = w[wx]; waSum += wwx * waSums[wx]; wcSum += wwx * wcSums[wx]; aSum += wwx * aSums[wx]; bSum += wwx * bSums[wx]; gSum += wwx * gSums[wx]; rSum += wwx * rSums[wx]; } } wcSum >>= 8; if (waSum == 0 || wcSum == 0) { SetColorAt(bbbDest, 0, y, new int[] { 0, 0, 0, 0 }); } else { int alpha = (int)(aSum / waSum); int blue = (int)(bSum / wcSum); int green = (int)(gSum / wcSum); int red = (int)(rSum / wcSum); SetColorAt(bbbDest, 0, y, new int[] { alpha, red, green, blue }); } for (int x = 1; x < applyRect.Width; ++x) { for (int i = 0; i < wlen - 1; ++i) { waSums[i] = waSums[i + 1]; wcSums[i] = wcSums[i + 1]; aSums[i] = aSums[i + 1]; bSums[i] = bSums[i + 1]; gSums[i] = gSums[i + 1]; rSums[i] = rSums[i + 1]; } waSum = 0; wcSum = 0; aSum = 0; bSum = 0; gSum = 0; rSum = 0; int wx; for (wx = 0; wx < wlen - 1; ++wx) { long wwx = (long)w[wx]; waSum += wwx * waSums[wx]; wcSum += wwx * wcSums[wx]; aSum += wwx * aSums[wx]; bSum += wwx * bSums[wx]; gSum += wwx * gSums[wx]; rSum += wwx * rSums[wx]; } wx = wlen - 1; waSums[wx] = 0; wcSums[wx] = 0; aSums[wx] = 0; bSums[wx] = 0; gSums[wx] = 0; rSums[wx] = 0; int srcX = x + wx - r; if (srcX >= 0 && srcX < applyRect.Width) { for (int wy = 0; wy < wlen; ++wy) { int srcY = y + wy - r; // only when in EDIT mode, ignore some pixels depending on preview quality if ((renderMode == RenderMode.EXPORT || rand.NextDouble() < previewQuality) && srcY >= 0 && srcY < applyRect.Height) { int[] colors = bbbSrc.GetColorArrayAt(srcX, srcY); int wp = w[wy]; waSums[wx] += wp; wp *= colors[0] + (colors[0] >> 7); wcSums[wx] += wp; wp >>= 8; aSums[wx] += wp * (long)colors[0]; bSums[wx] += wp * (long)colors[3]; gSums[wx] += wp * (long)colors[2]; rSums[wx] += wp * (long)colors[1]; } } int wr = w[wx]; waSum += (long)wr * waSums[wx]; wcSum += (long)wr * wcSums[wx]; aSum += (long)wr * aSums[wx]; bSum += (long)wr * bSums[wx]; gSum += (long)wr * gSums[wx]; rSum += (long)wr * rSums[wx]; } wcSum >>= 8; if (waSum == 0 || wcSum == 0) { SetColorAt(bbbDest, x, y, new int[] { 0, 0, 0, 0 }); } else { int alpha = (int)(aSum / waSum); int blue = (int)(bSum / wcSum); int green = (int)(gSum / wcSum); int red = (int)(rSum / wcSum); SetColorAt(bbbDest, x, y, new int[] { alpha, red, green, blue }); } } } } bbbDest.DrawTo(graphics, applyRect.Location); } }