private void EdgeDetectionRefresh() { if (image == null) { return; } Potrace.Clear(); ListOfPaths.Clear(); double scale = OrigImage.ActualHeight / image.Height; if (scale <= 0) { return; } int x = (int)(RectCutX / scale); int w = (int)(RectCutWidth / scale); int y = (int)(RectCutY / scale); int h = (int)(RectCutHeight / scale); Bitmap cutImage = CropBitmap(image, new Rectangle(x, y, w, h)); Potrace.Potrace_Trace(cutImage, ListOfPaths); EdgePathGeometry.AddListOfPaths(ListOfPaths); }
protected override void SolveInstance(IGH_DataAccess DA) { // Variables Bitmap bm; GrasshopperBitmapGoo ghbm = new GrasshopperBitmapGoo(); double t = 50.0; double a = 1.0; double mts = 2; bool opt = true; double opttol = 0.2; bool inv = false; int colorCount = 2; // Get Data from Input Params if (!DA.GetData(0, ref ghbm)) { return; } if (DA.GetData(1, ref t)) { if (0.0 > t || t > 100.0) { AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Threshold must lie between 0.0 to 100.0"); return; } } if (DA.GetData(2, ref a)) { if (0.0 > a || a > 1.0) { AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Corner Threshold must lie between 0.0 to 1.0"); return; } } DA.GetData(3, ref mts); DA.GetData(4, ref opt); if (DA.GetData(5, ref opttol)) { if (0.0 > opttol || opttol > 1.0) { AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Tolerance for Optimization must lie between 0.0 to 1.0"); return; } } DA.GetData(6, ref inv); if (DA.GetData(7, ref colorCount)) { if (colorCount < 0) { AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Color Count cannot be negative"); return; } } else { if (getColors) { AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Color Count not set. Setting 'Get Colors' to False. Please set a value for Color Count and re-enable Get Colors by right-clicking on the component"); getColors = false; } } // set Data in Potrace fields Potrace.Treshold = t / 100; Potrace.alphamax = a * (4 / 3); Potrace.turdsize = ((int)Math.Round(mts, 0, MidpointRounding.AwayFromZero)); Potrace.curveoptimizing = opt; Potrace.opttolerance = opttol; if (ghbm.IsValid && ghbm.Image != null) { bm = ghbm.Image; } else { AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Invalid Bitmap"); return; } // convert png transparent background to white if (!getColors || (colorCount == 0)) { using (Bitmap b = new Bitmap(bm.Width, bm.Height)) { b.SetResolution(bm.HorizontalResolution, bm.VerticalResolution); using (Graphics g = Graphics.FromImage(b)) { g.Clear(Color.White); g.DrawImageUnscaled(bm, 0, 0); } b.RotateFlip(RotateFlipType.RotateNoneFlipY); DataTree <Curve> crvs = new DataTree <Curve>(); Potrace.Potrace_Trace(b, crvs, inv); DA.SetDataTree(0, crvs); } } else { using (Bitmap b = new Bitmap(bm.Width, bm.Height)) { b.SetResolution(bm.HorizontalResolution, bm.VerticalResolution); using (Graphics g = Graphics.FromImage(b)) { g.Clear(Color.Transparent); g.DrawImageUnscaled(bm, 0, 0); } b.RotateFlip(RotateFlipType.RotateNoneFlipY); WuQuantizer quantizer = new WuQuantizer(); Bitmap quantized = (Bitmap)quantizer.QuantizeImage(b, colorCount + 1); Color[] colors = new Color[colorCount]; Array.Copy(quantized.Palette.Entries, 0, colors, 0, colorCount); DataTree <GH_Colour> colorsOut = new DataTree <GH_Colour>(); DataTree <Curve> crvs = new DataTree <Curve>(); for (int i = 0; i < colorCount; i++) { Bitmap temp = quantized.Clone(new Rectangle(0, 0, b.Width, b.Height), PixelFormat.Format32bppArgb); var bmData = temp.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb); unsafe { byte *p = (byte *)bmData.Scan0; int stopAddress = (int)p + bmData.Stride * bmData.Height; while ((int)p != stopAddress) { if (p[0] == colors[i].B && p[1] == colors[i].G && p[2] == colors[i].R && p[3] == colors[i].A) { p[0] = p[1] = p[2] = p[3] = 255; } else { p[0] = p[1] = p[2] = p[3] = 0; } p += 4; } temp.UnlockBits(bmData); List <Curve> curves = new List <Curve>(); Potrace.Potrace_Trace(temp, curves, true); crvs.AddRange(curves, new GH_Path(i)); if (inv) { Color invCol = Color.FromArgb(((int)colors[i].A), (255 - ((int)colors[i].R)), (255 - ((int)colors[i].G)), (255 - ((int)colors[i].B))); colorsOut.Add(new GH_Colour(invCol), new GH_Path(i)); } else { colorsOut.Add(new GH_Colour(colors[i]), new GH_Path(i)); } Potrace.Clear(); Potrace.Treshold = t / 100; Potrace.alphamax = a * (4 / 3); Potrace.turdsize = ((int)Math.Round(mts, 0, MidpointRounding.AwayFromZero)); Potrace.curveoptimizing = opt; Potrace.opttolerance = opttol; } } DA.SetDataTree(0, crvs); DA.SetDataTree(2, colorsOut); } } Rectangle3d boundary = new Rectangle3d(Plane.WorldXY, (double)bm.Width, (double)bm.Height); DA.SetData(1, boundary); }
protected override void SolveInstance(IGH_DataAccess DA) { DA.GetData(0, ref ImgPath); int t = 0; DA.GetData(1, ref t); Potrace.Treshold = (double)t / 100; DA.GetData(2, ref Potrace.alphamax); int policy = 0; DA.GetData(3, ref policy); Potrace.turnpolicy = (TurnPolicy)policy; DA.GetData(4, ref Potrace.turdsize); DA.GetData(5, ref Potrace.curveoptimizing); DA.GetData(6, ref Potrace.opttolerance); //DA.GetData(7, ref boundary); bool inv = false; DA.GetData(7, ref inv); int count = 0; DA.GetData(8, ref count); //Read and flip image bm = new Bitmap(ImgPath); bm.RotateFlip(RotateFlipType.RotateNoneFlipY); // convert to argb bm = bm.Clone(new Rectangle(0, 0, bm.Width, bm.Height), PixelFormat.Format32bppArgb); // get boundary int H = bm.Height; int W = bm.Width; Rectangle3d boundary = new Rectangle3d(Plane.WorldXY, W, H); DataTree <GH_Colour> GC = new DataTree <GH_Colour>(); DataTree <Curve> curves = new DataTree <Curve>(); if ((int)count < 1) { // convert png transparent background to white var b = new Bitmap(bm.Width, bm.Height); b.SetResolution(bm.HorizontalResolution, bm.VerticalResolution); using (var g = Graphics.FromImage(b)) { g.Clear(Color.White); g.DrawImageUnscaled(bm, 0, 0); } List <Curve> crvs = new List <Curve>(); Potrace.Potrace_Trace(b, crvs, inv); curves.AddRange(crvs); } else { // quantitize image Potrace.Treshold = 0.1; var quantizer = new WuQuantizer(); Bitmap quantized = (Bitmap)quantizer.QuantizeImage(bm, count + 1); Color[] colors = new Color[count]; Array.Copy(quantized.Palette.Entries, 0, colors, 0, count); // segment image by color // TODO, processing each color in parellel if (parallel) { for (int i = 0; i < colors.Length; i++) { Bitmap temp = quantized.Clone(new Rectangle(0, 0, bm.Width, bm.Height), PixelFormat.Format32bppArgb); var bmData = temp.LockBits(new Rectangle(0, 0, bm.Width, bm.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb); unsafe { byte *p = (byte *)bmData.Scan0; int stopAddress = (int)p + bmData.Stride * bmData.Height; while ((int)p != stopAddress) { if (p[0] == colors[i].B && p[1] == colors[i].G && p[2] == colors[i].R && p[3] == colors[i].A) { p[0] = p[1] = p[2] = p[3] = 255; } else { p[0] = p[1] = p[2] = p[3] = 0; } p += 4; } temp.UnlockBits(bmData); List <Curve> crvs = new List <Curve>(); Potrace.Potrace_Trace(temp, crvs, inv); curves.AddRange(crvs, new GH_Path(i)); GC.Add(new GH_Colour(colors[i]), new GH_Path(i)); Potrace.Clear(); } } } for (int i = 0; i < colors.Length; i++) { Bitmap temp = quantized.Clone(new Rectangle(0, 0, bm.Width, bm.Height), PixelFormat.Format32bppArgb); var bmData = temp.LockBits(new Rectangle(0, 0, bm.Width, bm.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb); unsafe { byte *p = (byte *)bmData.Scan0; int stopAddress = (int)p + bmData.Stride * bmData.Height; while ((int)p != stopAddress) { if (p[0] == colors[i].B && p[1] == colors[i].G && p[2] == colors[i].R && p[3] == colors[i].A) { p[0] = p[1] = p[2] = p[3] = 255; } else { p[0] = p[1] = p[2] = p[3] = 0; } p += 4; } temp.UnlockBits(bmData); List <Curve> crvs = new List <Curve>(); Potrace.Potrace_Trace(temp, crvs, inv); curves.AddRange(crvs, new GH_Path(i)); GC.Add(new GH_Colour(colors[i]), new GH_Path(i)); Potrace.Clear(); } } } DA.SetDataTree(0, curves); DA.SetData(1, boundary); DA.SetDataTree(2, GC); }
protected override void SolveInstance(IGH_DataAccess DA) { DA.GetData(0, ref ImgPath); int t = 0; DA.GetData(1, ref t); Potrace.Treshold = (double)t / 100; DA.GetData(2, ref Potrace.alphamax); int p = 0; DA.GetData(3, ref p); Potrace.turnpolicy = (TurnPolicy)p; DA.GetData(4, ref Potrace.turdsize); DA.GetData(5, ref Potrace.curveoptimizing); DA.GetData(6, ref Potrace.opttolerance); //DA.GetData(7, ref boundary); bool inv = false; DA.GetData(7, ref inv); bm = new Bitmap(ImgPath); bm.RotateFlip(RotateFlipType.RotateNoneFlipY); // convert png transparent background to white var b = new Bitmap(bm.Width, bm.Height); b.SetResolution(bm.HorizontalResolution, bm.VerticalResolution); using (var g = Graphics.FromImage(b)) { g.Clear(Color.White); g.DrawImageUnscaled(bm, 0, 0); } double H = bm.Height; double W = bm.Width; Rectangle3d boundary = new Rectangle3d(Plane.WorldXY, W, H); /* * // phsical size * double bh = boundary.Y.Length; * double bw = boundary.X.Length; * // scale Factor * double fh = bh / H; * double fw = bw / W; */ if (treeOutput) { DataTree <Curve> crvs = new DataTree <Curve>(); Potrace.Potrace_Trace(b, crvs, inv); DA.SetDataTree(0, crvs); } else { List <Curve> crvs = new List <Curve>(); Potrace.Potrace_Trace(b, crvs, inv); DA.SetDataList(0, crvs); } DA.SetData(1, boundary); }
private void Trace() { Potrace.Clear(); ListOfPathes.Clear(); Potrace.Potrace_Trace(sourceImage, ListOfPathes); }