Example #1
0
        public void Render(Image image, Drawable drawable, bool preview)
        {
            int size = GetValue<int>("size");

              image.UndoGroupStart();

              var procedure = new Procedure("plug_in_pixelize");
              procedure.Run(image, drawable, size);

              var palette = new MinisteckPalette();
              image.ConvertIndexed(ConvertDitherType.No, ConvertPaletteType.Custom,
               0, false, false, "Ministeck");
              palette.Delete();

              image.ConvertRgb();
              image.UndoGroupEnd();

              // And finally calculate the Ministeck pieces

              using (var painter = new Painter(drawable, size, GetValue<RGB>("color")))
            {
              Shape.Painter = painter;

              int width = drawable.Width / size;
              int height = drawable.Height / size;

              var A = new BoolMatrix(width, height);

              // Fill in shapes
              bool limit = GetValue<bool>("limit");
              var shapes = new ShapeSet();
              shapes.Add((limit) ? 2 : 1, new TwoByTwoShape());
              shapes.Add((limit) ? 8 : 1, new ThreeByOneShape());
              shapes.Add((limit) ? 3 : 1, new TwoByOneShape());
              shapes.Add((limit) ? 2 : 1, new CornerShape());
              shapes.Add((limit) ? 1 : 1, new OneByOneShape());

              Action<int> update = null;
              if (!preview)
            {
              var progress = new Progress(_("Ministeck..."));
              update = y => progress.Update((double) y / height);
            }

              var generator =
            new CoordinateGenerator(new Rectangle(0, 0, width, height), update);
              generator.ForEach(c => {if (!A.Get(c)) shapes.Fits(A, c);});
            }

              drawable.Flush();
              drawable.Update();
        }
Example #2
0
        public void Render(Image image, Drawable drawable, Progress progress)
        {
            var dimensions = image.Dimensions;

              Tile.CacheDefault(drawable);
              var pf = new PixelFetcher(drawable, false);

              var iter = new RgnIterator(drawable, RunMode.Interactive);
              iter.IterateSrcDest(src => src);

              int dropSize = GetValue<int>("drop_size");
              int fishEye = GetValue<int>("fish_eye");
              int number = GetValue<int>("number");

              var factory = new RaindropFactory(dropSize, fishEye, dimensions);

              for (int numBlurs = 0; numBlurs <= number; numBlurs++)
            {
              var raindrop = factory.Create();
              if (raindrop == null)
            {
              if (progress != null)
            progress.Update(1.0);
              break;
            }

              raindrop.Render(factory.BoolMatrix, pf, drawable);

              if (progress != null)
            progress.Update((double) numBlurs / number);
            }

              pf.Dispose();

              drawable.Flush();
              drawable.Update();
        }
Example #3
0
        protected override void Render(Image image, Drawable drawable)
        {
            var progress = new Progress(_("Colorizing..."));

              var rectangle = drawable.MaskIntersect;
              // Fix me: replace with x1, y1, x2, y2
              int i = rectangle.X1;
              int j = rectangle.Y1;
              int ii = rectangle.X2;
              int jj = rectangle.Y2;

              bool hasSel = (rectangle != null);
              if (!hasSel || _useEntireImage)
            {
              j = i = 0;
              jj = image.Width;
              ii = image.Height;
            }

              Drawable sel = null;
              int threshGuc = (int) (_thresh * 255);
              PixelRgn selRgn = null;

              if (hasSel)
            {
              sel = image.Selection;
              selRgn = new PixelRgn(sel, rectangle, false, false);
            }

              var srcRgn = new PixelRgn(drawable, rectangle, false, false);
              var dstRgn = new PixelRgn(drawable, rectangle, true, true);
              var markRgn = new PixelRgn(_marked, rectangle, false, false);

              int h = srcRgn.H;
              int w = srcRgn.W;

              var A = new double[WindowPixels, h * w];
              var AI = new int[WindowPixels * h * w];
              var AJ = new int[WindowPixels * h * w];

              var Y = new double[h, w];
              var I = new double[h, w];
              var Q = new double[h, w];

              double[,] inI = null;
              double[,] inQ = null;
              if (_useChroma)
            {
              inI = new double[h, w];
              inQ = new double[h, w];
            }

              bool[,] mask = new bool[h, w];

              Tile.CacheDefault(drawable);

              if (sel != null)
            {
              // Retarded check for selections, because gimp doesn't
              // _REALLY_ return FALSE when there's no selection.
              if (j == 0 && i == 0 && jj == drawable.Width &&
              ii == drawable.Height)
            {
              bool goodSelection = false;
              foreach (var pixel in
               new ReadPixelIterator(sel, RunMode.Noninteractive))
            {
              if (pixel[0] != 0)
            {
              goodSelection = true;
              break;
            }
            }
              if (!goodSelection)
            {
              sel.Detach();
              sel = null;
            }
            }
            }

              Pixel[] selRow = null;
              var whitePixel = new Pixel(255, 255, 255);

              for (i = 0; i < h; i++)
            {
              var imgRow = srcRgn.GetRow(srcRgn.X, srcRgn.Y + i, w);
              var markRow = markRgn.GetRow(markRgn.X, markRgn.Y + i, w);

              if (sel != null)
              {
            selRow = selRgn.GetRow(selRgn.X, selRgn.Y + i, w);
              }

              for (j = 0; j < w; j++)
            {
              var imgPixel = imgRow[j];
              var markPixel = markRow[j];
              int selIdx = (sel != null) ? j : 0;

              double iY, iI, iQ;
              double mY;

              rgb2yiq(imgPixel, out iY, out iI, out iQ);

              if (_useChroma)
            {
              inI[i, j] = iI;
              inQ[i, j] = iQ;
            }

              if (_includeOriginal)
            {
              var diff = imgPixel - markPixel;;
              int delta = Math.Abs(diff.Red) + Math.Abs(diff.Green) +
            Math.Abs(diff.Blue);
            }

              // big dirty if statement
              if (_pureWhite && markPixel.IsSameColor(whitePixel))
            {
              mask[i, j] = true;
            }
              else if ((_includeOriginal && !imgPixel.IsSameColor(markPixel))
               || (!_includeOriginal && markPixel.Alpha >= threshGuc))
            {
              mask[i, j] = true;
              rgb2yiq(markPixel, out mY, out iI, out iQ);
            }
              else if (sel != null && selRow[selIdx].Red < threshGuc)
            {
              mask[i, j] = true;
            }
              else {
              mask[i, j] = false;
              iI = iQ = 0;
              }

              Y[i, j] = iY;
              I[i, j] = iI;
              Q[i, j] = iQ;
            }
            }

              if (sel != null)
            {
              sel.Detach();
            }

              progress.Update(0.1);

              int n = 0;
              for (i = 0; i < h; i++)
            {
              for (j = 0; j < w; j++)
            {
              if (!mask[i, j])
            {
              int min_ii = Math.Max(0, i - WindowRadius);
              int max_ii = Math.Min(h - 1, i + WindowRadius);
              int min_jj = Math.Max(0, j - WindowRadius);
              int max_jj = Math.Min(w - 1, j + WindowRadius);
              var vary = new int[WindowPixels];
              var varx = new int[WindowPixels];
              var var = new double[WindowPixels];

              int count = 0;
              double sum_sq = 0;
              double sum = 0;
              double min_variance = 1.0;

              for (ii = min_ii; ii <= max_ii; ii++)
            {
              for (jj = min_jj; jj <= max_jj; jj++)
            {
              double val = Y[ii, jj];
              sum += val;
              sum_sq += val * val;

              if (ii == i && jj == j)
                continue;

              vary[count] = i * w + j;
              varx[count] = ii * w + jj;
              var[count] = val - Y[i, j];
              var[count] *= var[count];
              if (_useChroma)
                {
                  val = inI[ii, jj] - inI[i, j];
                  var[count] += val * val;
                  val = inQ[ii, jj] - inQ[i, j];
                  var[count] += val * val;
                }
              if (var[count] < min_variance)
                min_variance = var[count];
              ++count;
            }
            }

              double sigma =
            (sum_sq - (sum * sum)/(double)(count + 1)) / (double)count;
              if (sigma < 0.000002)
            sigma = 0.000002;
              else if (sigma < (min_variance / LN_100))
            sigma = min_variance / LN_100;

              sum = 0;
              for (ii = 0; ii < count; ii++)
            {
              var[ii] = Math.Exp(-var[ii] / sigma);
              sum += var[ii];
            }

              for (ii = 0; ii < count; ii++)
            {
              AI[n] = vary[ii];
              AJ[n] = varx[ii];
              // Fix me: just A[i, j]?
              A[n / (h * w) , n % (h * w)] = -var[ii] / sum;
              ++n;
            }
            }

              AI[n] = AJ[n] = i * w + j;
              // Fix me: just A[i, j]?
              A[n / (h * w), n % (h * w)] = 1.0;
              ++n;
            }
            }

              UmfPack umf = new UmfPack();
              umf.Defaults();

              var Ax = new double[WindowPixels, h * w];
              var Ap = new int[h * w + 1];
              var Ai = new int[WindowPixels * h * w];
              var Map = new int[WindowPixels * h * w];

              umf.TripletToCol(h * w, h * w, n, AI, AJ, A, Ap, Ai, Ax, Map);

              umf.Symbolic(h * w, h * w, Ap, Ai, Ax);
              umf.Numeric(Ap, Ai, Ax);
              umf.FreeSymbolic();

              progress.Update(0.3);

              var outI = new double[h, w];
              var outQ = new double[h, w];

              umf.Solve(Ap, Ai, Ax, outI, I);

              progress.Update(0.6);

              umf.Solve(Ap, Ai, Ax, outQ, Q);
              umf.FreeNumeric();

              progress.Update(0.9);

              for (i = 0; i < h; i++)
            {
              // FIXME: This is only for the alpha channel..
              var imgRow = srcRgn.GetRow(srcRgn.X, srcRgn.Y + i, w);

              for (j = 0; j < w; j++)
            {
              yiq2rgb(Y[i, j], outI[i, j], outQ[i, j], imgRow[j]);
            }

              dstRgn.SetRow(imgRow, dstRgn.X, dstRgn.Y + i);
              }

              drawable.Flush();
              drawable.MergeShadow(true);
              drawable.Update(dstRgn.X, dstRgn.Y, dstRgn.W, dstRgn.H);

              progress.Update(1.0);
        }