Пример #1
0
 /// <summary>
 /// Gets the Potrace settings from the plug-in settings file.
 /// </summary>
 private void GetPotraceSettings()
 {
     Potrace.RestoreDefaults();
     if (Settings.TryGetInteger("turnpolicy", out var turnpolicy))
     {
         Potrace.turnpolicy = (TurnPolicy)turnpolicy;
     }
     if (Settings.TryGetInteger("turdsize", out var turdsize))
     {
         Potrace.turdsize = turdsize;
     }
     if (Settings.TryGetDouble("alphamax", out var alphamax))
     {
         Potrace.alphamax = alphamax;
     }
     if (Settings.TryGetBool("curveoptimizing", out var curveoptimizing))
     {
         Potrace.curveoptimizing = curveoptimizing;
     }
     if (Settings.TryGetDouble("opttolerance", out var opttolerance))
     {
         Potrace.opttolerance = opttolerance;
     }
     if (Settings.TryGetDouble("Treshold", out var Treshold))
     {
         Potrace.Treshold = Treshold;
     }
 }
Пример #2
0
        private void btnLoad_Click(object sender, RoutedEventArgs e)
        {
            Microsoft.Win32.OpenFileDialog op = new Microsoft.Win32.OpenFileDialog();
            op.Title  = "Select a picture";
            op.Filter = "All supported graphics|*.jpg;*.jpeg;*.png|" +
                        "JPEG (*.jpg;*.jpeg)|*.jpg;*.jpeg|" +
                        "Portable Network Graphic (*.png)|*.png" +
                        "|BMP Windows Bitmap (*.bmp)|*.bmp";

            if (op.ShowDialog() == true)
            {
                imgPhoto.Source       = new BitmapImage(new Uri(op.FileName));
                save_button.IsEnabled = true;
                ListOfCurveArray      = null;
                if (Bitmap != null)
                {
                    Bitmap.Dispose();
                }
                Bitmap = new Bitmap(op.FileName);
                refreshMatrix();
                vectorize();
                Svg = Potrace.Export2SVG(ListOfCurveArray, Bitmap.Width, Bitmap.Height);

                if (HasAtleastOneClue && !string.IsNullOrWhiteSpace(Word.Text))
                {
                    save.IsEnabled = true;
                }
            }
        }
Пример #3
0
 /// <summary>
 /// Vectorize
 /// </summary>
 /// <param name="sender"></param>
 /// <param name="e"></param>
 private void button2_Click(object sender, EventArgs e)
 {
     ListOfCurveArray = new ArrayList();
     Potrace.turdsize = Convert.ToInt32(textBox1.Text);
     try
     {
         Potrace.alphamax = Convert.ToDouble(textBox3.Text);
     }
     catch
     {
         textBox3.Text = Potrace.alphamax.ToString();
     }
     try
     {
         Potrace.opttolerance = Convert.ToDouble(textBox2.Text);
     }
     catch
     {
         textBox2.Text = Potrace.opttolerance.ToString();
     }
     //optimize the path p, replacing sequences of Bezier segments by a
     //single segment when possible.
     Potrace.curveoptimizing = true; //checkBox3.Checked;
     Matrix = Potrace.BitMapToBinary(Bitmap, trackBar2.Value);
     Potrace.potrace_trace(Matrix, ListOfCurveArray);
     refreshMatrix();
 }
Пример #4
0
        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);
        }
Пример #5
0
        public void CsPotrace_PotraceTrace_LoadBitmap_Points()
        {
            using var bmp = getSquare();
            Potrace po     = new Potrace();
            var     result = po.PotraceTrace(bmp);

            var points = result[0].SelectMany(p => new dPoint[] { p.A, p.B }).ToArray();

            Assert.Equal(8, points.Length);

            Assert.Equal(2, points[0].X);
            Assert.Equal(5, points[0].Y);
            Assert.Equal(5, points[1].X);
            Assert.Equal(8, points[1].Y);
            Assert.Equal(5, points[2].X);
            Assert.Equal(8, points[2].Y);
            Assert.Equal(8, points[3].X);
            Assert.Equal(5, points[3].Y);
            Assert.Equal(8, points[4].X);
            Assert.Equal(5, points[4].Y);
            Assert.Equal(5, points[5].X);
            Assert.Equal(2, points[5].Y);
            Assert.Equal(5, points[6].X);
            Assert.Equal(2, points[6].Y);
            Assert.Equal(2, points[7].X);
            Assert.Equal(5, points[7].Y);
        }
Пример #6
0
        private List <Models.Game.Path> ConvertBitmapToStrokes(Bitmap bitmap)
        {
            bool[,] Matrix;
            ArrayList ListOfCurveArray; ListOfCurveArray = new ArrayList();

            Matrix = Potrace.BitMapToBinary(bitmap, 150);
            Potrace.potrace_trace(Matrix, ListOfCurveArray);

            string selectedColor = "Black";
            int    lineSize      = 11;
            string shape         = "rond";
            var    listOfStrokes = new List <Models.Game.Path>();
            var    canvasId      = Guid.NewGuid().ToString();

            for (int i = 0; i < ListOfCurveArray.Count; i++)
            {
                ArrayList CurveArray = (ArrayList)ListOfCurveArray[i];
                for (int j = 0; j < CurveArray.Count; j++)
                {
                    Potrace.Curve[] Curves = (Potrace.Curve[])CurveArray[j];
                    var             stroke = new Models.Game.Path(Guid.NewGuid().ToString(), canvasId, lineSize, selectedColor, false, shape);
                    for (int k = 0; k < Curves.Length; k++)
                    {
                        if (Curves[k].Kind == Potrace.CurveKind.Bezier)
                        {
                            stroke.Coordinates.Add(new Coordinate()
                            {
                                X = Curves[k].A.X, Y = Curves[k].A.Y
                            });
                            stroke.Coordinates.Add(new Coordinate()
                            {
                                X = Curves[k].ControlPointA.X, Y = Curves[k].ControlPointA.Y
                            });
                            stroke.Coordinates.Add(new Coordinate()
                            {
                                X = Curves[k].ControlPointB.X, Y = Curves[k].ControlPointB.Y
                            });
                            stroke.Coordinates.Add(new Coordinate()
                            {
                                X = Curves[k].B.X, Y = Curves[k].B.Y
                            });
                        }
                        else
                        {
                            stroke.Coordinates.Add(new Coordinate()
                            {
                                X = Curves[k].A.X, Y = Curves[k].A.Y
                            });
                            stroke.Coordinates.Add(new Coordinate()
                            {
                                X = Curves[k].B.X, Y = Curves[k].B.Y
                            });
                        }
                    }
                    listOfStrokes.Add(stroke);
                }
            }

            return(listOfStrokes);
        }
Пример #7
0
 private void refreshMatrix()
 {
     if (Bitmap == null)
     {
         return;
     }
     Matrix = Potrace.BitMapToBinary(Bitmap, (int)contrastSlider.Value);
     refreshPicture();
 }
Пример #8
0
 private void refreshMatrix()
 {
     if (Bitmap == null)
     {
         return;
     }
     Matrix = Potrace.BitMapToBinary(Bitmap, trackBar2.Value);
     refreshPicture();
 }
Пример #9
0
        public void CsPotrace_PotraceTrace_LoadBitmap_CurveCount()
        {
            using var bmp = getSquare();
            Potrace po     = new Potrace();
            var     result = po.PotraceTrace(bmp);

            Assert.Single(result); // External List
            Assert.Equal(4, result[0].Count);
        }
Пример #10
0
        private void refreshPicture()
        {
            if (Matrix == null)
            {
                return;
            }
            Bitmap b = Potrace.BinaryToBitmap(Matrix, true);

            imgPhoto.Source = BitmapToImageSource(b);
        }
Пример #11
0
        public void CsPotrace_PotraceTrace_LoadBitmap_CurveCountCircle()
        {
            using var bmp = getCircle();
            Potrace po     = new Potrace();
            var     result = po.PotraceTrace(bmp);

            var points = result[0].SelectMany(p => new dPoint[] { p.A, p.B }).ToArray();

            Assert.Equal(8, points.Length);
        }
Пример #12
0
        private void RefreshSvg()
        {
            string svg     = Potrace.getSVG();
            string StdPath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData, Environment.SpecialFolderOption.Create) + "\\Drawing3d.svg";

            System.IO.StreamWriter W = new System.IO.StreamWriter(StdPath);
            W.WriteLine(svg);
            W.Flush();
            W.Close();
            webSvg.Navigate(new Uri(StdPath));
        }
Пример #13
0
        private void vectorize()
        {
            ListOfCurveArray        = new ArrayList();
            Potrace.turdsize        = Convert.ToInt32(contrastSlider.Value);
            Potrace.curveoptimizing = true;
            Matrix = Potrace.BitMapToBinary(Bitmap, (int)contrastSlider.Value);
            Potrace.potrace_trace(Matrix, ListOfCurveArray);
            Bitmap s = Potrace.Export2GDIPlus(ListOfCurveArray, Bitmap.Width, Bitmap.Height);

            imgPhoto.Source = BitmapToImageSource(s);
            refreshMatrix();
        }
Пример #14
0
        /// <summary>
        /// Vectorize the image
        /// </summary>
        void Vectorize()

        {
            Bitmap               = new Bitmap(loaded_Image);
            ListOfCurveArray     = new ArrayList();
            Potrace.turdsize     = ignore_area_pixel;
            Potrace.alphamax     = AlphaMax;
            Potrace.opttolerance = curve_tolerance;

            Potrace.curveoptimizing = Curveoptimizing;
            Matrix = Potrace.BitMapToBinary(Bitmap, tresHold);
            Potrace.potrace_trace(Matrix, ListOfCurveArray);
            ListElement_Image = new List <List <object> >();
            ListOfLine        = new List <LineF>();
        }
Пример #15
0
 private void saveAsCSVToolStripMenuItem_Click(object sender, EventArgs e)
 {
     if (ListOfCurveArray == null)
     {
         MessageBox.Show("Please vectorize the image first");
         return;
     }
     if (saveFileDialog1.ShowDialog() == DialogResult.OK)
     {
         string s = Potrace.Export2SVG(ListOfCurveArray, Bitmap.Width, Bitmap.Height);
         System.IO.StreamWriter FS = new System.IO.StreamWriter(saveFileDialog1.FileName);
         FS.Write(s);
         FS.Close();
     }
 }
Пример #16
0
 private void ExportSVG(object sender, RoutedEventArgs e)
 {
     if (sourceImage == null)
     {
         return;
     }
     if (SaveFileDialog.ShowDialog() == true)
     {
         string svg               = Potrace.getSVG();
         string StdPath           = SaveFileDialog.FileName;
         System.IO.StreamWriter W = new System.IO.StreamWriter(StdPath);
         W.WriteLine(svg);
         W.Flush();
         W.Close();
     }
 }
Пример #17
0
        private void PreviewVector(Bitmap bmp)
        {
            Potrace.turdsize        = (int)(UseSpotRemoval ? SpotRemoval : 2);
            Potrace.alphamax        = UseSmoothing ? (double)Smoothing : 0.0;
            Potrace.opttolerance    = UseOptimize ? (double)Optimize : 0.2;
            Potrace.curveoptimizing = UseOptimize;             //optimize the path p, replacing sequences of Bezier segments by a single segment when possible.

            if (MustExitTH)
            {
                return;
            }

            List <List <CsPotrace.Curve> > plist = Potrace.PotraceTrace(bmp);

            if (MustExitTH)
            {
                return;
            }

            using (Graphics g = Graphics.FromImage(bmp))
            {
                g.Clear(Color.White);                 //remove original image

                using (Brush fill = new SolidBrush(Color.FromArgb(FillingDirection != Direction.None ? 255 : 30, Color.Black)))
                    Potrace.Export2GDIPlus(plist, g, fill, null, 1);                     //trace filling

                if (MustExitTH)
                {
                    return;
                }

                PreviewLineByLine(bmp);                 //process filling with line by line preview

                if (MustExitTH)
                {
                    return;
                }

                Potrace.Export2GDIPlus(plist, g, null, Pens.Red, 0);                 //trace borders

                if (MustExitTH)
                {
                    return;
                }
            }
        }
Пример #18
0
 /// <summary>
 /// Camキャプチャーメイン処理
 /// </summary>
 void camCaptureTimerElapsed(object sender, System.Timers.ElapsedEventArgs e)
 {
     if (!CamCaptureBusy)
     {
         try {
             CamCaptureBusy = true;
             FpsAct.Value   = 1000d / (DateTime.Now - lastTime).Milliseconds;
             lastTime       = DateTime.Now;
             CapturedBmp    = CamNewFrame(cam);
             Potrace.Trace(CapturedBmp, (int)TraceThreshold, TracePitch);
             tracedSvgStr      = traceSvgStr;
             tracedFaces       = Potrace.TraceFaces(traceSvgStr);
             CapturedBmf.Value = CapturedBmp.ToBitmapFrame();
             TracedBmf.Value   = TracedBmp.ToBitmapFrame();
             CamCaptureBusy    = false;
         } catch (Exception) { }
     }
 }
Пример #19
0
 /// <summary>
 /// Scrキャプチャーメイン処理
 /// </summary>
 void scrCaptureTimerElapsed(object sender, System.Timers.ElapsedEventArgs e)
 {
     if (!ScrCaptureBusy)
     {
         try {
             ScrCaptureBusy = true;
             FpsAct.Value   = 1000d / (DateTime.Now - lastTime).Milliseconds;
             lastTime       = DateTime.Now;
             CapturedBmp    = ScreenCapture.Instance.CaptureScreen((int)DocPoint.X, (int)DocPoint.Y, (int)DocSize.Width, (int)DocSize.Height);
             CapturedBmp.Save(@"C:\Users\tg30266\Desktop\test.png");
             Potrace.Trace(CapturedBmp, (int)TraceThreshold, TracePitch);
             tracedSvgStr      = traceSvgStr;
             tracedFaces       = Potrace.TraceFaces(traceSvgStr);
             CapturedBmf.Value = CapturedBmp.ToBitmapFrame();
             TracedBmf.Value   = TracedBmp.ToBitmapFrame();
             ScrCaptureBusy    = false;
         } catch (Exception) { ScrCaptureBusy = false; }
     }
 }
Пример #20
0
        public void CsPotrace_Export2GCode_Export2GCode_0010()
        {
            using var bmp = PotraceTraceTests.getSquare();
            var trace = new Potrace().PotraceTrace(bmp);
            // Image size is only used for DEBUG (static variable hardocded to FALSE)
            var gcodeLines = Potrace.Export2GCode(trace, 0, 0, 10, "ON", "OFF", bmp.Size);

            Assert.Equal(11, gcodeLines.Count);
            Assert.Equal("G0 X0.2 Y0.5", gcodeLines[0]);
            Assert.Equal("ON", gcodeLines[1]);
            Assert.Equal("G1 X0.288 Y0.712", gcodeLines[2]);
            Assert.Equal("G2 X0.5 Y0.8 I0.212 J-0.212", gcodeLines[3]);
            Assert.Equal("G2 X0.712 Y0.712 I0 J-0.3", gcodeLines[4]);
            Assert.Equal("G1 X0.8 Y0.5", gcodeLines[5]);
            Assert.Equal("G1 X0.712 Y0.288", gcodeLines[6]);
            Assert.Equal("G2 X0.5 Y0.2 I-0.212 J0.212", gcodeLines[7]);
            Assert.Equal("G2 X0.288 Y0.288 I0 J0.3", gcodeLines[8]);
            Assert.Equal("G1 X0.2 Y0.5", gcodeLines[9]);
            Assert.Equal("OFF", gcodeLines[10]);
        }
Пример #21
0
        private void saveAsSVG(object sender, EventArgs e)
        {
            vectorize();
            System.Windows.Forms.SaveFileDialog saveFileDialog = new System.Windows.Forms.SaveFileDialog();
            saveFileDialog.DefaultExt = "svg";
            saveFileDialog.FileName   = "*.svg";
            saveFileDialog.Filter     = "svg files (*.svg)|*.svg";



            if (saveFileDialog.ShowDialog() == DialogResult.OK)
            {
                // le fichier svg a envoyer à la bd.
                string s = Potrace.Export2SVG(ListOfCurveArray, Bitmap.Width, Bitmap.Height);
                // on ne gardera pas ça mais c'est utile pareil
                System.IO.StreamWriter FS = new System.IO.StreamWriter(saveFileDialog.FileName);
                FS.Write(s);
                FS.Close();
            }
        }
Пример #22
0
        public void CsPotrace_Export2GCode_Export2GCode_N5520()
        {
            using var bmp = PotraceTraceTests.getSquare();
            var trace = new Potrace().PotraceTrace(bmp);
            // Image size is only used for DEBUG (static variable hardocded to FALSE)
            var gcodeLines = Potrace.Export2GCode(trace, -5, -5, 20, "ON", "OFF", bmp.Size);

            Assert.Equal(11, gcodeLines.Count);
            Assert.Equal("G0 X-4.9 Y-4.75", gcodeLines[0]);
            Assert.Equal("ON", gcodeLines[1]);
            Assert.Equal("G1 X-4.856 Y-4.644", gcodeLines[2]);
            Assert.Equal("G2 X-4.75 Y-4.6 I0.106 J-0.106", gcodeLines[3]);
            Assert.Equal("G2 X-4.644 Y-4.644 I0 J-0.15", gcodeLines[4]);
            Assert.Equal("G1 X-4.6 Y-4.75", gcodeLines[5]);
            Assert.Equal("G1 X-4.644 Y-4.856", gcodeLines[6]);
            Assert.Equal("G2 X-4.75 Y-4.9 I-0.106 J0.106", gcodeLines[7]);
            Assert.Equal("G2 X-4.856 Y-4.856 I0 J0.15", gcodeLines[8]);
            Assert.Equal("G1 X-4.9 Y-4.75", gcodeLines[9]);
            Assert.Equal("OFF", gcodeLines[10]);
        }
Пример #23
0
        /// <summary>
        /// refresh picture
        /// </summary>
        private void refreshPicture()
        {
            if (Matrix == null)
            {
                return;
            }
            if (radioButton1.Checked)
            {
                Bitmap B = Potrace.BinaryToBitmap(Matrix, true);
                pictureBox1.Width  = B.Width * (trackBar1.Value + 1);
                pictureBox1.Height = B.Height * (trackBar1.Value + 1);
                pictureBox1.Image  = B;
            }
            else
            {
                Bitmap B = new Bitmap(Matrix.GetLength(0) * (trackBar2.Value + 1), Matrix.GetLength(1) * (trackBar2.Value + 1));
                pictureBox1.Width  = B.Width;
                pictureBox1.Height = B.Height;
                pictureBox1.Image  = B;
            }

            draw();
        }
Пример #24
0
        public void LoadImagePotrace(Bitmap bmp, string filename, bool UseSpotRemoval, int SpotRemoval, bool UseSmoothing, decimal Smoothing, bool UseOptimize, decimal Optimize, L2LConf c)
        {
            bmp.RotateFlip(RotateFlipType.RotateNoneFlipY);

            long start = Tools.HiResTimer.TotalMilliseconds;

            mTotalTravelOff   = 0;
            mTotalTravelOn    = 0;
            mEstimatedTimeOff = TimeSpan.Zero;
            mEstimatedTimeOn  = TimeSpan.Zero;
            list.Clear();
            mRange.ResetRange();

            Potrace.turdsize        = (int)(UseSpotRemoval ? SpotRemoval : 2);
            Potrace.alphamax        = UseSmoothing ? (double)Smoothing : 0.0;
            Potrace.opttolerance    = UseOptimize ? (double)Optimize : 0.2;
            Potrace.curveoptimizing = UseOptimize;             //optimize the path p, replacing sequences of Bezier segments by a single segment when possible.

            List <List <CsPotrace.Curve> > plist = Potrace.PotraceTrace(bmp);

            if (c.dir != RasterConverter.ImageProcessor.Direction.None)
            {
                using (Bitmap ptb = new Bitmap(bmp.Width, bmp.Height))
                {
                    using (Graphics g = Graphics.FromImage(ptb))
                    {
                        //Potrace.Export2GDIPlus(plist, g, Brushes.Black, null, (Math.Max(c.res/c.fres, 1) + 1) / 2.0f);
                        Potrace.Export2GDIPlus(plist, g, Brushes.Black, null, Math.Max(1, c.res / c.fres));
                        using (Bitmap resampled = RasterConverter.ImageTransform.ResizeImage(ptb, new Size((int)(bmp.Width * c.fres / c.res), (int)(bmp.Height * c.fres / c.res)), true, InterpolationMode.HighQualityBicubic))
                        {
                            //absolute
                            list.Add(new GrblCommand("G90"));
                            //use travel speed
                            list.Add(new GrblCommand(String.Format("F{0}", c.travelSpeed)));
                            //move fast to offset
                            list.Add(new GrblCommand(String.Format("G0 X{0} Y{1}", formatnumber(c.oX), formatnumber(c.oY))));
                            if (c.pwm)
                            {
                                list.Add(new GrblCommand(String.Format("{0} S0", c.lOn)));                                 //laser on and power to zero
                            }
                            else
                            {
                                list.Add(new GrblCommand(String.Format("{0} S255", c.lOff)));                                 //laser off and power to max power
                            }
                            //set speed to markspeed
                            list.Add(new GrblCommand(String.Format("G1 F{0}", c.markSpeed)));
                            //relative
                            list.Add(new GrblCommand("G91"));


                            c.vectorfilling = true;
                            ImageLine2Line(resampled, c);

                            //laser off
                            list.Add(new GrblCommand(c.lOff));
                        }
                    }
                }
            }

            //absolute
            list.Add(new GrblCommand("G90"));
            //use travel speed
            list.Add(new GrblCommand(String.Format("F{0}", c.travelSpeed)));
            //move fast to offset
            list.Add(new GrblCommand(String.Format("G0 X{0} Y{1}", formatnumber(c.oX), formatnumber(c.oY))));
            //laser off and power to maxPower
            list.Add(new GrblCommand(String.Format("{0} S{1}", c.lOff, c.maxPower)));
            //set speed to borderspeed
            list.Add(new GrblCommand(String.Format("G1 F{0}", c.borderSpeed)));

            //trace borders
            List <string> gc = Potrace.Export2GCode(plist, c.oX, c.oY, c.res, c.lOn, c.lOff, bmp.Size);

            foreach (string code in gc)
            {
                list.Add(new GrblCommand(code));
            }


            //laser off
            list.Add(new GrblCommand(String.Format("{0}", c.lOff)));

            //move fast to origin
            list.Add(new GrblCommand("G0 X0 Y0"));

            Analyze();
            long elapsed = Tools.HiResTimer.TotalMilliseconds - start;

            if (OnFileLoaded != null)
            {
                OnFileLoaded(elapsed, filename);
            }
        }
        /// <summary>
        /// Creates the content of the dialog
        /// </summary>
        private RhinoDialogTableLayout CreateTableLayout()
        {
            // Create controls and define behaviors

            var ns_threshold = new NumericUpDownWithUnitParsing
            {
                ValueUpdateMode = NumericUpDownWithUnitParsingUpdateMode.WhenDoneChanging,
                MinValue        = 0.0,
                MaxValue        = 100.0,
                DecimalPlaces   = 0,
                Increment       = 1.0,
                ToolTip         = "Weighted RGB color evaluation threshold.",
                Value           = (int)(Potrace.Treshold * 100.0), Width = 45
            };

            var sld_threshold = new Slider
            {
                MinValue      = 0,
                MaxValue      = 100,
                TickFrequency = 25,
                Value         = (int)(Potrace.Treshold * 100.0),
                Width         = 220
            };

            ns_threshold.ValueChanged += (sender, args) =>
            {
                if (m_allow_update_and_redraw)
                {
                    m_allow_update_and_redraw = false;
                    Potrace.Treshold          = ns_threshold.Value / 100.0;
                    sld_threshold.Value       = (int)(Potrace.Treshold * 100.0);
                    m_allow_update_and_redraw = true;
                    UpdateAndRedraw();
                }
            };

            sld_threshold.ValueChanged += (sender, args) =>
            {
                if (m_allow_update_and_redraw)
                {
                    m_allow_update_and_redraw = false;
                    Potrace.Treshold          = sld_threshold.Value / 100.0;
                    ns_threshold.Value        = (int)(Potrace.Treshold * 100.0);
                    m_allow_update_and_redraw = true;
                    UpdateAndRedraw();
                }
            };

            var dd_turnpolicy = new DropDown
            {
                ToolTip = "Algorithm used to resolve ambiguities in path decomposition."
            };

            foreach (var str in Enum.GetNames(typeof(TurnPolicy)))
            {
                dd_turnpolicy.Items.Add(str);
            }
            dd_turnpolicy.SelectedIndex         = (int)Potrace.turnpolicy;
            dd_turnpolicy.SelectedIndexChanged += (sender, args) =>
            {
                if (dd_turnpolicy.SelectedIndex != 0)
                {
                    Potrace.turnpolicy = (TurnPolicy)dd_turnpolicy.SelectedIndex;
                    UpdateAndRedraw();
                }
            };

            var ns_turdsize = new NumericUpDownWithUnitParsing
            {
                ValueUpdateMode = NumericUpDownWithUnitParsingUpdateMode.WhenDoneChanging,
                MinValue        = 1.0,
                MaxValue        = 100.0,
                DecimalPlaces   = 0,
                Increment       = 1.0,
                ToolTip         = "Filter speckles of up to this size in pixels.",
                Value           = Potrace.turdsize
            };

            ns_turdsize.ValueChanged += (sender, args) =>
            {
                Potrace.turdsize = (int)ns_turdsize.Value;
                UpdateAndRedraw();
            };

            var ns_alphamax = new NumericUpDownWithUnitParsing
            {
                ValueUpdateMode = NumericUpDownWithUnitParsingUpdateMode.WhenDoneChanging,
                MinValue        = 0.0,
                MaxValue        = 100.0,
                DecimalPlaces   = 0,
                Increment       = 1.0,
                ToolTip         = "Corner rounding threshold.",
                Value           = Potrace.alphamax
            };

            ns_alphamax.ValueChanged += (sender, args) =>
            {
                Potrace.alphamax = ns_alphamax.Value;
                UpdateAndRedraw();
            };

            var chk_curveoptimizing = new CheckBox
            {
                ThreeState = false,
                ToolTip    = "Optimize of Bézier segments by a single segment when possible.",
                Checked    = Potrace.curveoptimizing
            };

            var ns_opttolerance = new NumericUpDownWithUnitParsing
            {
                ValueUpdateMode = NumericUpDownWithUnitParsingUpdateMode.WhenDoneChanging,
                MinValue        = 0.1,
                MaxValue        = 1.0,
                DecimalPlaces   = 1,
                Increment       = 0.1,
                Enabled         = Potrace.curveoptimizing,
                ToolTip         = "Tolerance used to optimize Bézier segments.",
                Value           = Potrace.opttolerance
            };

            chk_curveoptimizing.CheckedChanged += (sender, args) =>
            {
                Potrace.curveoptimizing = chk_curveoptimizing.Checked.Value;
                ns_opttolerance.Enabled = Potrace.curveoptimizing;
                UpdateAndRedraw();
            };

            ns_opttolerance.ValueChanged += (sender, args) =>
            {
                Potrace.opttolerance = ns_opttolerance.Value;
                UpdateAndRedraw();
            };

            var btn_reset = new Button
            {
                Text = "Restore Defaults"
            };

            btn_reset.Click += (sender, args) =>
            {
                m_allow_update_and_redraw = false;
                Potrace.RestoreDefaults();
                sld_threshold.Value         = (int)(Potrace.Treshold * 100.0);
                ns_threshold.Value          = sld_threshold.Value;
                dd_turnpolicy.SelectedIndex = (int)Potrace.turnpolicy;
                ns_turdsize.Value           = Potrace.turdsize;
                ns_alphamax.Value           = Potrace.alphamax;
                chk_curveoptimizing.Checked = Potrace.curveoptimizing;
                ns_opttolerance.Value       = Potrace.opttolerance;
                m_allow_update_and_redraw   = true;
                UpdateAndRedraw();
            };

            // Layout the controls

            var minimum_size = new Eto.Drawing.Size(150, 0);

            var layout = new RhinoDialogTableLayout(false)
            {
                Spacing = new Eto.Drawing.Size(10, 8)
            };

            layout.Rows.Add(new TableRow(new TableCell(new LabelSeparator {
                Text = "Vectorization options"
            }, true)));

            var panel0 = new Panel {
                MinimumSize = minimum_size, Content = new Label()
                {
                    Text = "Threshold"
                }
            };
            var table0 = new TableLayout {
                Padding = new Eto.Drawing.Padding(8, 0, 0, 0)
            };

            table0.Rows.Add(new TableRow(new TableCell(panel0), new TableCell(sld_threshold, true), new TableCell(ns_threshold)));
            layout.Rows.Add(table0);

            var panel1 = new Panel {
                MinimumSize = minimum_size, Content = new Label()
                {
                    Text = "Turn policy"
                }
            };
            var table1 = new TableLayout {
                Padding = new Eto.Drawing.Padding(8, 0, 0, 0), Spacing = new Size(10, 8)
            };

            table1.Rows.Add(new TableRow(new TableCell(panel1), new TableCell(dd_turnpolicy)));
            table1.Rows.Add(new TableRow(new TableCell(new Label()
            {
                Text = "Filter size"
            }), new TableCell(ns_turdsize)));
            table1.Rows.Add(new TableRow(new TableCell(new Label()
            {
                Text = "Corner rounding"
            }), new TableCell(ns_alphamax)));
            layout.Rows.Add(table1);

            layout.Rows.Add(new TableRow(new TableCell(new LabelSeparator {
                Text = "Curve optimization"
            }, true)));

            var panel2 = new Panel {
                MinimumSize = minimum_size, Content = new Label()
                {
                    Text = "Optimizing"
                }
            };
            var table2 = new TableLayout {
                Padding = new Eto.Drawing.Padding(8, 0, 0, 0), Spacing = new Size(10, 8)
            };

            table2.Rows.Add(new TableRow(new TableCell(panel2), new TableCell(chk_curveoptimizing)));
            table2.Rows.Add(new TableRow(new TableCell(new Label()
            {
                Text = "Tolerance"
            }), new TableCell(ns_opttolerance)));
            table2.Rows.Add(null);
            table2.Rows.Add(new TableRow(new TableCell(new Label()
            {
                Text = ""
            }), new TableCell(btn_reset)));
            layout.Rows.Add(table2);

            return(layout);
        }
Пример #26
0
        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);
        }
Пример #27
0
        /// <summary>
        /// Command.RunCommand override
        /// </summary>
        protected override Result RunCommand(RhinoDoc doc, RunMode mode)
        {
            Potrace.Clear();

            // Prompt the user for the name of the image file to vectorize.
            string path = GetImageFileName(mode);

            if (string.IsNullOrEmpty(path))
            {
                return(Result.Cancel);
            }

            // Creates a bitmap from the specified file.
            var bitmap = Image.FromFile(path) as Bitmap;

            if (null == bitmap)
            {
                RhinoApp.WriteLine("The specified file cannot be identifed as a supported type.");
                return(Result.Failure);
            }

            // Verify bitmap size
            if (0 == bitmap.Width || 0 == bitmap.Height)
            {
                RhinoApp.WriteLine("Error reading the specified file.");
                return(Result.Failure);
            }

            // Calculate scale factor so curves of a reasonable size are added to Rhino
            var unit_scale = (doc.ModelUnitSystem != UnitSystem.Inches)
        ? RhinoMath.UnitScale(UnitSystem.Inches, doc.ModelUnitSystem)
        : 1.0;
            var scale = (double)(1.0 / bitmap.HorizontalResolution * unit_scale);

            // I'm not convinced this is useful...
            if (true)
            {
                var format = $"F{doc.DistanceDisplayPrecision}";

                // Print image size in pixels
                RhinoApp.WriteLine("Image size in pixels: {0} x {1}",
                                   bitmap.Width,
                                   bitmap.Height
                                   );

                // Print image size in inches
                var width  = (double)(bitmap.Width / bitmap.HorizontalResolution);
                var height = (double)(bitmap.Height / bitmap.VerticalResolution);
                RhinoApp.WriteLine("Image size in inches: {0} x {1}",
                                   width.ToString(format, CultureInfo.InvariantCulture),
                                   height.ToString(format, CultureInfo.InvariantCulture)
                                   );

                // Image size in in model units, if needed
                if (doc.ModelUnitSystem != UnitSystem.Inches)
                {
                    width  = (double)(bitmap.Width / bitmap.HorizontalResolution * unit_scale);
                    height = (double)(bitmap.Height / bitmap.VerticalResolution * unit_scale);
                    RhinoApp.WriteLine("Image size in {0}: {1} x {2}",
                                       doc.ModelUnitSystem.ToString().ToLower(),
                                       width.ToString(format, CultureInfo.InvariantCulture),
                                       height.ToString(format, CultureInfo.InvariantCulture)
                                       );
                }
            }

            // Convert the bitmap to an Eto bitmap
            var eto_bitmap = ConvertBitmapToEto(bitmap);

            if (null == eto_bitmap)
            {
                RhinoApp.WriteLine("Unable to convert image to Eto bitmap.");
                return(Result.Failure);
            }

            // 12-Jan-2021 Dale Fugier
            // This should prevent Eto.Drawing.BitmapData.GetPixels() from throwing an exception
            if (!IsCompatibleBitmap(eto_bitmap))
            {
                RhinoApp.WriteLine("The image has an incompatible pixel format. Please select an image with 24 or 32 bits per pixel, or 8 bit indexed.");
                return(Result.Failure);
            }

            // This bitmap is not needed anymore, so dispose of it
            bitmap.Dispose();

            // Gets the Potrace settings from the plug-in settings file
            GetPotraceSettings();

            // Create the conduit, which does most of the work
            var conduit = new VectorizeConduit(
                eto_bitmap,
                scale,
                doc.ModelAbsoluteTolerance,
                m_select_output
          ? Rhino.ApplicationSettings.AppearanceSettings.SelectedObjectColor
          : doc.Layers.CurrentLayer.Color
                )
            {
                Enabled = true
            };

            if (mode == RunMode.Interactive)
            {
                // Show the interactive dialog box
                var dialog = new VectorizeDialog(doc, conduit);
                dialog.RestorePosition();
                var result = dialog.ShowSemiModal(doc, RhinoEtoApp.MainWindow);
                dialog.SavePosition();
                if (result != Result.Success)
                {
                    conduit.Enabled = false;
                    Potrace.Clear();
                    doc.Views.Redraw();
                    return(Result.Cancel);
                }
            }
            else
            {
                // Show the command line options
                var go = new GetOption();
                go.SetCommandPrompt("Vectorization options. Press Enter when done");
                go.AcceptNothing(true);
                while (true)
                {
                    conduit.TraceBitmap();
                    doc.Views.Redraw();

                    go.ClearCommandOptions();

                    // IgnoreArea
                    var turdsize_opt = new OptionInteger(Potrace.turdsize, 2, 100);
                    var turdsize_idx = go.AddOptionInteger("FilterSize", ref turdsize_opt, "Filter speckles of up to this size in pixels");

                    // TurnPolicy
                    var turnpolicy_idx = go.AddOptionEnumList("TurnPolicy", Potrace.turnpolicy);

                    // Optimizing
                    var curveoptimizing_opt = new OptionToggle(Potrace.curveoptimizing, "No", "Yes");
                    var curveoptimizing_idx = go.AddOptionToggle("Optimizing", ref curveoptimizing_opt);

                    // Tolerance
                    var opttolerance_opt = new OptionDouble(Potrace.opttolerance, 0.0, 1.0);
                    var opttolerance_idx = go.AddOptionDouble("Tolerance", ref opttolerance_opt, "Optimizing tolerance");

                    // CornerThreshold
                    var alphamax_opt = new OptionDouble(Potrace.alphamax, 0.0, 100.0);
                    var alphamax_idx = go.AddOptionDouble("CornerRounding", ref alphamax_opt, "Corner rounding threshold");

                    // Threshold
                    var threshold_opt = new OptionDouble(Potrace.Treshold, 0.0, 100.0);
                    var threshold_idx = go.AddOptionDouble("Threshold", ref threshold_opt, "Threshold");

                    // RestoreDefaults
                    var defaults_idx = go.AddOption("RestoreDefaults");

                    var res = go.Get();

                    if (res == GetResult.Option)
                    {
                        var option = go.Option();
                        if (null != option)
                        {
                            if (turdsize_idx == option.Index)
                            {
                                Potrace.turdsize = turdsize_opt.CurrentValue;
                            }

                            if (turnpolicy_idx == option.Index)
                            {
                                var list = Enum.GetValues(typeof(TurnPolicy)).Cast <TurnPolicy>().ToList();
                                Potrace.turnpolicy = list[option.CurrentListOptionIndex];
                            }

                            if (curveoptimizing_idx == option.Index)
                            {
                                Potrace.curveoptimizing = curveoptimizing_opt.CurrentValue;
                            }

                            if (opttolerance_idx == option.Index)
                            {
                                Potrace.opttolerance = opttolerance_opt.CurrentValue;
                            }

                            if (alphamax_idx == option.Index)
                            {
                                Potrace.alphamax = alphamax_opt.CurrentValue;
                            }

                            if (threshold_idx == option.Index)
                            {
                                Potrace.Treshold = threshold_opt.CurrentValue;
                            }

                            if (defaults_idx == option.Index)
                            {
                                Potrace.RestoreDefaults();
                            }
                        }
                        continue;
                    }

                    if (res != GetResult.Nothing)
                    {
                        conduit.Enabled = false;
                        doc.Views.Redraw();
                        Potrace.Clear();
                        return(Result.Cancel);
                    }

                    break;
                }
            }

            // Group curves
            var attributes = doc.CreateDefaultAttributes();

            attributes.AddToGroup(doc.Groups.Add());
            for (var i = 0; i < conduit.OutlineCurves.Count; i++)
            {
                var rhobj_id = doc.Objects.AddCurve(conduit.OutlineCurves[i], attributes);
                if (m_select_output)
                {
                    var rhobj = doc.Objects.Find(rhobj_id);
                    if (null != rhobj)
                    {
                        rhobj.Select(true);
                    }
                }
            }

            conduit.Enabled = false;
            Potrace.Clear();
            doc.Views.Redraw();

            // Set the Potrace settings to the plug -in settings file.
            SetPotraceSettings();

            return(Result.Success);
        }
Пример #28
0
        private static string GetHolePath(Potrace.Curve[] Curves)
        {
            StringBuilder path = new StringBuilder();

            for (int i = Curves.Length-1; i >=0 ; i--)
            {
                Potrace.Curve Curve = Curves[i];

                if (i == Curves.Length - 1)
                {
                    path.AppendLine("M" + Curve.B.x.ToString("0.0", enUsCulture) + " " + Curve.B.y.ToString("0.0", enUsCulture));
                }

                if (Curve.Kind == Potrace.CurveKind.Bezier)
                {

                    path.Append("C" + Curve.ControlPointB.x.ToString("0.0", enUsCulture) + " " + Curve.ControlPointB.y.ToString("0.0", enUsCulture) + " " +
                                  Curve.ControlPointA.x.ToString("0.0", enUsCulture) + " " + Curve.ControlPointA.y.ToString("0.0", enUsCulture) + " " +
                                  Curve.A.x.ToString("0.0", enUsCulture) + " " + Curve.A.y.ToString("0.0", enUsCulture));

                }
                if (Curve.Kind == Potrace.CurveKind.Line)
                {
                    path.Append("L" + Curve.B.x.ToString("0.0", enUsCulture) + " " + Curve.B.y.ToString("0.0", enUsCulture));

                }
                if (i == 0)
                {
                    path.Append("Z");
                }
                else
                {
                    path.AppendLine("");
                }

            }

            return path.ToString();
        }
 protected override void BeforeSolveInstance()
 {
     base.BeforeSolveInstance();
     Potrace.Clear();
 }
        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);
        }
Пример #31
0
 /// <summary>
 /// Trace the bitmap using Potrace.
 /// </summary>
 public void TraceBitmap()
 {
     Clear();
     Potrace.Clear();
     Potrace.Potrace_EtoTrace(m_bitmap, m_path_curves);
 }