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 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;
            }
        }
Exemple #3
0
        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);
            }
        }