コード例 #1
0
        public void ImageShouldBeOverlayedByFilledPolygon()
        {
            string path = this.CreateOutputDirectory("Drawing", "FilledBezier");

            SixLabors.Primitives.PointF[] simplePath = new SixLabors.Primitives.PointF[] {
                new Vector2(10, 400),
                new Vector2(30, 10),
                new Vector2(240, 30),
                new Vector2(300, 400)
            };
            using (Image <Rgba32> image = new Image <Rgba32>(500, 500))
            {
                image
                .BackgroundColor(Rgba32.Blue)
                .Fill(Rgba32.HotPink, new Polygon(new CubicBezierLineSegment(simplePath)))
                .Save($"{path}/Simple.png");

                using (PixelAccessor <Rgba32> sourcePixels = image.Lock())
                {
                    Assert.Equal(Rgba32.HotPink, sourcePixels[150, 300]);

                    //curve points should not be never be set
                    Assert.Equal(Rgba32.Blue, sourcePixels[240, 30]);

                    // inside shape should not be empty
                    Assert.Equal(Rgba32.HotPink, sourcePixels[200, 250]);
                }
            }
        }
コード例 #2
0
        public void ImageShouldBeOverlayedByFilledPolygonOpacity()
        {
            string path       = TestEnvironment.CreateOutputDirectory("Drawing", "FilledPolygons");
            var    simplePath = new SixLabors.Primitives.PointF[] {
                new Vector2(10, 10),
                new Vector2(200, 150),
                new Vector2(50, 300)
            };
            var color = new Rgba32(Rgba32.HotPink.R, Rgba32.HotPink.G, Rgba32.HotPink.B, 150);

            using (var image = new Image <Rgba32>(500, 500))
            {
                image.Mutate(x => x
                             .BackgroundColor(Rgba32.Blue)
                             .FillPolygon(color, simplePath));
                image.Save($"{path}/Opacity.png");

                //shift background color towards forground color by the opacity amount
                var mergedColor = new Rgba32(Vector4.Lerp(Rgba32.Blue.ToVector4(), Rgba32.HotPink.ToVector4(), 150f / 255f));

                using (PixelAccessor <Rgba32> sourcePixels = image.Lock())
                {
                    Assert.Equal(Rgba32.Blue, sourcePixels[2, 2]);
                }
            }
        }
コード例 #3
0
        public void ImageShouldBeOverlayedByFilledPolygonNoAntialias()
        {
            string path = TestEnvironment.CreateOutputDirectory("Drawing", "FilledPolygons");

            SixLabors.Primitives.PointF[] simplePath = new SixLabors.Primitives.PointF[] {
                new Vector2(10, 10),
                new Vector2(200, 150),
                new Vector2(50, 300)
            };

            using (Image <Rgba32> image = new Image <Rgba32>(500, 500))
            {
                image.Mutate(x => x
                             .BackgroundColor(Rgba32.Blue)
                             .FillPolygon(Rgba32.HotPink, simplePath, new GraphicsOptions(false)));
                image.Save($"{path}/Simple_NoAntialias.png");

                using (PixelAccessor <Rgba32> sourcePixels = image.Lock())
                {
                    Assert.Equal(Rgba32.HotPink, sourcePixels[11, 11]);

                    Assert.Equal(Rgba32.HotPink, sourcePixels[199, 150]);

                    Assert.Equal(Rgba32.HotPink, sourcePixels[50, 50]);

                    Assert.Equal(Rgba32.Blue, sourcePixels[2, 2]);
                }
            }
        }
コード例 #4
0
        public void ImageShouldBeOverlayedByFilledPolygonNoAntialias()
        {
            string path       = TestEnvironment.CreateOutputDirectory("Drawing", "FilledPolygons");
            var    simplePath = new SixLabors.Primitives.PointF[] {
                new Vector2(10, 10),
                new Vector2(200, 150),
                new Vector2(50, 300)
            };

            using (var image = new Image <Rgba32>(500, 500))
            {
                image.Mutate(
                    x => x.BackgroundColor(Rgba32.Blue).FillPolygon(
                        new GraphicsOptions(false),
                        Rgba32.HotPink,
                        simplePath));
                image.Save($"{path}/Simple_NoAntialias.png");

                Buffer2D <Rgba32> sourcePixels = image.GetRootFramePixelBuffer();
                Assert.True(Rgba32.HotPink == sourcePixels[11, 11], "[11, 11] wrong");

                Assert.True(Rgba32.HotPink == sourcePixels[199, 149], "[199, 149] wrong");

                Assert.True(Rgba32.HotPink == sourcePixels[50, 50], "[50, 50] wrong");

                Assert.True(Rgba32.Blue == sourcePixels[2, 2], "[2, 2] wrong");
            }
        }
コード例 #5
0
        public void ImageShouldBeOverlayedByFilledPolygonOpacity()
        {
            string path = this.CreateOutputDirectory("Drawing", "FilledBezier");

            SixLabors.Primitives.PointF[] simplePath = new SixLabors.Primitives.PointF[] {
                new Vector2(10, 400),
                new Vector2(30, 10),
                new Vector2(240, 30),
                new Vector2(300, 400)
            };
            Rgba32 color = new Rgba32(Rgba32.HotPink.R, Rgba32.HotPink.G, Rgba32.HotPink.B, 150);

            using (Image <Rgba32> image = new Image <Rgba32>(500, 500))
            {
                image
                .BackgroundColor(Rgba32.Blue)
                .Fill(color, new Polygon(new CubicBezierLineSegment(simplePath)))
                .Save($"{path}/Opacity.png");

                //shift background color towards forground color by the opacity amount
                Rgba32 mergedColor = new Rgba32(Vector4.Lerp(Rgba32.Blue.ToVector4(), Rgba32.HotPink.ToVector4(), 150f / 255f));

                using (PixelAccessor <Rgba32> sourcePixels = image.Lock())
                {
                    //top of curve
                    Assert.Equal(mergedColor, sourcePixels[138, 116]);

                    //curve points should not be never be set
                    Assert.Equal(Rgba32.Blue, sourcePixels[240, 30]);

                    // inside shape should not be empty
                    Assert.Equal(mergedColor, sourcePixels[200, 250]);
                }
            }
        }
コード例 #6
0
 static PointF Offset(PointF point, SizeF direction, float distance)
 {
     return(new PointF()
     {
         X = point.X + direction.Width * distance,
         Y = point.Y + direction.Height * distance,
     });
 }
コード例 #7
0
        public override Image Render(string mode = "human")
        {
            float       b, t, r, l;
            const int   screen_width  = 600;
            const int   screen_height = 400;
            const float world_width   = x_threshold * 2;
            const float scale         = screen_width / world_width;
            const int   carty         = 300;
            const float polewidth     = 10.0f;
            const float poleheight    = scale * (2 * length);
            const float cartwidth     = 50.0f;
            const float cartheight    = 30.0f;


            if (_viewer == null)
            {
                lock (this) {
                    //to prevent double initalization.
                    if (_viewer == null)
                    {
                        if (_viewerFactory == null)
                        {
                            _viewerFactory = NullEnvViewer.Factory;
                        }
                        _viewer = _viewerFactory(screen_width, screen_height, "cartpole-v1");
                    }
                }
            }

            //pole
            l = -polewidth / 2;
            r = polewidth / 2;
            t = poleheight - polewidth / 2;
            b = -polewidth / 2;
            var pole   = new RectangularPolygon(-polewidth / 2, carty - poleheight, polewidth, poleheight);
            var circle = new EllipsePolygon(0, carty - polewidth / 2, polewidth / 2);

            //cart
            l = -cartwidth / 2;
            r = cartwidth / 2;
            t = cartheight / 2;
            b = -cartheight / 2;
            var axleoffset = cartheight / 4.0;
            var cart       = new RectangularPolygon(-cartwidth / 2, carty - cartheight / 2, cartwidth, cartheight);
            var draw       = new List <(IPath, Rgba32)>();

            if (!(state is null))
            {
                var center_x = (float)(state.GetDouble(0) * scale + screen_width / 2.0f);
                //no y cuz it doesnt change.
                var cbounds    = circle.Bounds;
                var pivotPoint = new PointF(cbounds.X + cbounds.Width / 2f, cbounds.Y + cbounds.Height / 2f);

                draw.Add((cart.Translate(center_x, 0), Rgba32.Black));
                draw.Add((pole.Transform(Matrix3x2.CreateRotation((float)state.GetDouble(2), pivotPoint)).Translate(center_x, 0), new Rgba32(204, 153, 102)));
                draw.Add((circle.Translate(center_x, 0), Rgba32.Teal));
            }
コード例 #8
0
        private void Render(int lineCount)
        {
            Stopwatch stopwatch = Stopwatch.StartNew();

            using (var image = new Image <SixLabors.ImageSharp.PixelFormats.Rgba32>(600, 400))
            {
                image.Mutate(imageContext =>
                {
                    // draw background
                    var bgColor = SixLabors.ImageSharp.PixelFormats.Rgba32.FromHex("#003366");
                    imageContext.BackgroundColor(bgColor);

                    for (int i = 0; i < lineCount; i++)
                    {
                        // create an array of two points to make the straight line
                        var points = new SixLabors.Primitives.PointF[2];
                        points[0]  = new SixLabors.Primitives.PointF(
                            x: (float)(rand.NextDouble() * pictureBox1.Width),
                            y: (float)(rand.NextDouble() * pictureBox1.Height));
                        points[1] = new SixLabors.Primitives.PointF(
                            x: (float)(rand.NextDouble() * pictureBox1.Width),
                            y: (float)(rand.NextDouble() * pictureBox1.Height));

                        // create a pen unique to this line
                        var lineColor = SixLabors.ImageSharp.Color.FromRgba(
                            r: (byte)rand.Next(255),
                            g: (byte)rand.Next(255),
                            b: (byte)rand.Next(255),
                            a: (byte)rand.Next(255));
                        float lineWidth = rand.Next(1, 10);
                        var linePen     = new SixLabors.ImageSharp.Processing.Pen(lineColor, lineWidth);

                        // draw the line
                        imageContext.DrawLines(linePen, points);
                    }
                });

                // render onto an Image
                var stream = new System.IO.MemoryStream();
                image.SaveAsBmp(stream);
                System.Drawing.Image img = System.Drawing.Image.FromStream(stream);

                pictureBox1.Image?.Dispose();
                pictureBox1.Image = img;
            }

            stopwatch.Stop();
            renderTimesMsec.Add(1000.0 * stopwatch.ElapsedTicks / Stopwatch.Frequency);
            double mean = renderTimesMsec.Sum() / renderTimesMsec.Count();

            Debug.WriteLine($"Render {renderTimesMsec.Count:00} " +
                            $"took {renderTimesMsec.Last():0.000} ms " +
                            $"(running mean: {mean:0.000} ms)");

            Application.DoEvents();
        }
コード例 #9
0
        static SizeF Vector(PointF start, PointF end)
        {
            var dx     = end.X - start.X;
            var dy     = end.Y - start.Y;
            var length = Math.Sqrt(dx * dx + dy * dy);

            return(new SizeF()
            {
                Width = (float)(dx / length),
                Height = (float)(dy / length)
            });
        }
コード例 #10
0
        public void ImageShouldBeOverlayedByFilledPolygonWithPattern()
        {
            string path       = TestEnvironment.CreateOutputDirectory("Drawing", "FilledPolygons");
            var    simplePath = new SixLabors.Primitives.PointF[] {
                new Vector2(10, 10),
                new Vector2(200, 150),
                new Vector2(50, 300)
            };

            using (var image = new Image <Rgba32>(500, 500))
            {
                image.Mutate(
                    x => x.FillPolygon(new GraphicsOptions(true), Brushes.Horizontal(Rgba32.HotPink), simplePath));
                image.Save($"{path}/Pattern.png");

                Buffer2D <Rgba32> sourcePixels = image.GetRootFramePixelBuffer();
                Assert.Equal(Rgba32.HotPink, sourcePixels[81, 145]);
            }
        }
コード例 #11
0
        public void DrawBeziers <TPixel>(TestImageProvider <TPixel> provider, string colorName, byte alpha, float thickness)
            where TPixel : struct, IPixel <TPixel>
        {
            var points = new SixLabors.Primitives.PointF[]
            {
                new Vector2(10, 400), new Vector2(30, 10), new Vector2(240, 30), new Vector2(300, 400)
            };
            Rgba32 rgba = TestUtils.GetColorByName(colorName);

            rgba.A = alpha;
            Color color = rgba;

            FormattableString testDetails = $"{colorName}_A{alpha}_T{thickness}";

            provider.RunValidatingProcessorTest(x => x.DrawBeziers(color, 5f, points),
                                                testDetails,
                                                appendSourceFileOrDescription: false,
                                                appendPixelTypeToFileName: false);
        }
コード例 #12
0
        public void ImageShouldBeOverlayedByFilledPolygonImage()
        {
            string path       = TestEnvironment.CreateOutputDirectory("Drawing", "FilledPolygons");
            var    simplePath = new SixLabors.Primitives.PointF[] {
                new Vector2(10, 10),
                new Vector2(200, 150),
                new Vector2(50, 300)
            };

            using (Image <Rgba32> brushImage = TestFile.Create(TestImages.Bmp.Car).CreateRgba32Image())
                using (var image = new Image <Rgba32>(500, 500))
                {
                    var brush = new ImageBrush <Rgba32>(brushImage);

                    image.Mutate(x => x.BackgroundColor(Rgba32.Blue));
                    image.Mutate(x => x.FillPolygon(brush, simplePath));
                    image.Save($"{path}/Image.png");
                }
        }
コード例 #13
0
        public void FillPolygon_Concave <TPixel>(TestImageProvider <TPixel> provider)
            where TPixel : struct, IPixel <TPixel>
        {
            var points = new SixLabors.Primitives.PointF[]
            {
                new Vector2(8, 8),
                new Vector2(64, 8),
                new Vector2(64, 64),
                new Vector2(120, 64),
                new Vector2(120, 120),
                new Vector2(8, 120)
            };

            var color = Color.LightGreen;

            provider.RunValidatingProcessorTest(
                c => c.FillPolygon(color, points),
                appendSourceFileOrDescription: false,
                appendPixelTypeToFileName: false);
        }
コード例 #14
0
        public void ImageShouldBeOverlayedByFilledPolygonWithPattern()
        {
            string path = this.CreateOutputDirectory("Drawing", "FilledPolygons");

            SixLabors.Primitives.PointF[] simplePath = new SixLabors.Primitives.PointF[] {
                new Vector2(10, 10),
                new Vector2(200, 150),
                new Vector2(50, 300)
            };

            using (Image <Rgba32> image = new Image <Rgba32>(500, 500))
            {
                image
                .FillPolygon(Brushes.Horizontal(Rgba32.HotPink), simplePath, new GraphicsOptions(true))
                .Save($"{path}/Pattern.png");

                using (PixelAccessor <Rgba32> sourcePixels = image.Lock())
                {
                    Assert.Equal(Rgba32.HotPink, sourcePixels[81, 145]);
                }
            }
        }
コード例 #15
0
        public void DrawTriangle(PointF a, PointF b, PointF c, string color, int penWidth, bool isFill)
        {
            var a1     = ToPointF(a, world);
            var b1     = ToPointF(b, world);
            var c1     = ToPointF(c, world);
            var points = new SixLabors.Primitives.PointF[] { a1, b1, c1, a1 };

            if (isFill)
            {
                commandQueue.Enqueue(ctx =>
                {
                    ctx.FillPolygon(Rgba32.FromHex(color), points, currentOption);
                });
            }
            else
            {
                commandQueue.Enqueue(ctx =>
                {
                    ctx.DrawPolygon(Rgba32.FromHex(color), penWidth, points, currentOption);
                });
            }
        }
コード例 #16
0
        private unsafe Texture CreateTexture(TextKey key)
        {
            var size       = key.Size;
            var actualFont = key.Font;

            var image = _textImagePool.Acquire(new ImageKey
            {
                Width  = (int)Math.Ceiling(size.X),
                Height = (int)Math.Ceiling(size.Y)
            });

            // Clear image to transparent.
            // TODO: Don't need to do this for a newly created image.
            fixed(void *pin = &image.DangerousGetPinnableReferenceToPixelBuffer())
            {
                Unsafe.InitBlock(pin, 0, (uint)(image.Width * image.Height * 4));
            }

            image.Mutate(x =>
            {
                var location = new SixLabors.Primitives.PointF(0, size.Y / 2.0f);

                // TODO: Vertical centering is not working properly.
                location.Y *= 0.8f;

                var color = key.Color;

                x.DrawText(
                    new TextGraphicsOptions
                {
                    WrapTextWidth       = size.X,
                    HorizontalAlignment = key.Alignment == TextAlignment.Center
                            ? HorizontalAlignment.Center
                            : HorizontalAlignment.Left,
                    VerticalAlignment = VerticalAlignment.Center
                },
                    key.Text,
                    actualFont,
                    new Bgra32(
                        (byte)(color.R * 255.0f),
                        (byte)(color.G * 255.0f),
                        (byte)(color.B * 255.0f),
                        (byte)(color.A * 255.0f)),
                    location);
            });

            Texture texture;

            // Draw image to texture.
            fixed(void *pin = &image.DangerousGetPinnableReferenceToPixelBuffer())
            {
                texture = _graphicsDevice.ResourceFactory.CreateTexture(
                    TextureDescription.Texture2D(
                        (uint)image.Width,
                        (uint)image.Height,
                        1,
                        1,
                        PixelFormat.B8_G8_R8_A8_UNorm,
                        TextureUsage.Sampled));

                _graphicsDevice.UpdateTexture(
                    texture,
                    new IntPtr(pin),
                    (uint)(image.Width * image.Height * 4),
                    0, 0, 0,
                    texture.Width,
                    texture.Height,
                    1,
                    0,
                    0);
            }

            _textImagePool.ReleaseAll();

            return(texture);
        }
コード例 #17
0
        public static void GenerateAll(List <GqlResponse_Data_Subreddit_Layers_Edge> edges)
        {
            //Create the source image and fill it with white
            Image <Rgba32> image = new Image <Rgba32>(1920, 1080 + 100);

            for (int x = 0; x < image.Width; x++)
            {
                for (int y = 0; y < image.Height; y++)
                {
                    image[x, y] = new Rgba32(1f, 1f, 1f, 1f);
                }
            }

            //Load font
            FontCollection fonts    = new FontCollection();
            FontFamily     fontFam  = fonts.Install("RobotoMono-Regular.ttf");
            var            mainFont = fontFam.CreateFont(40);
            var            mainFontRendererOptions = new RendererOptions(mainFont);
            var            smallFont = fontFam.CreateFont(20);
            var            smallFontRendererOptions = new RendererOptions(smallFont);

            //Start generation
            int saved = 0;
            int i     = 0;

            Console.WriteLine("[Canvas] Starting generation...");
            List <Task> tasks = new List <Task>();

            foreach (var e in edges)
            {
                i++;

                //Skip if this edge does not have an image
                if (!File.Exists(Program.OUTPUT_IMGS + e.node.id + ".png"))
                {
                    continue;
                }

                //Add this edge to the image. First, open it
                try
                {
                    using (FileStream fs = new FileStream(Program.OUTPUT_IMGS + e.node.id + ".png", FileMode.Open))
                        using (Image <Rgba32> edgeImg = Image.Load <Rgba32>(fs))
                        {
                            //Resize the image
                            int sizeX = e.node.box.endPoint.x - e.node.box.startPoint.x;
                            int sizeY = e.node.box.endPoint.y - e.node.box.startPoint.y;
                            //edgeImg.Mutate(x => x.Resize(sizeX, sizeY));
                            edgeImg.Mutate(x => x.Resize(100, 100));

                            //Copy the image
                            for (int x = 0; x < edgeImg.Width; x++)
                            {
                                for (int y = 0; y < edgeImg.Height; y++)
                                {
                                    //Mix color
                                    Rgba32 sourcePixel = image[x + e.node.box.startPoint.x, y + e.node.box.startPoint.y];
                                    Rgba32 edgePixel   = edgeImg[x, y];
                                    float  edgeMult    = ((float)edgePixel.A) / 255;
                                    float  sourceMult  = 1 - edgeMult;
                                    Rgba32 mixedColor  = new Rgba32(
                                        ((((float)edgePixel.R) / 255) * edgeMult) + ((((float)sourcePixel.R) / 255) * sourceMult),
                                        ((((float)edgePixel.G) / 255) * edgeMult) + ((((float)sourcePixel.G) / 255) * sourceMult),
                                        ((((float)edgePixel.B) / 255) * edgeMult) + ((((float)sourcePixel.B) / 255) * sourceMult),
                                        ((((float)edgePixel.A) / 255) * edgeMult) + ((((float)sourcePixel.A) / 255) * sourceMult)
                                        );
                                    image[x + e.node.box.startPoint.x, y + e.node.box.startPoint.y] = mixedColor;
                                }
                            }
                        }
                }
                catch (UnknownImageFormatException err)
                {
                    //Move image to the corrupted folder
                    File.Move(Program.OUTPUT_IMGS + e.node.id + ".png", Program.OUTPUT_IMGS_CORRUPT + e.node.id + ".png");
                }
                catch (Exception ex)
                {
                    //Different error.
                    Console.Write("\r[Canvas] Failed to process image " + e.node.id + "! " + ex.Message + ex.StackTrace + "\n");
                }

                //Save every 6th image
                if (i % 8 == 0)
                {
                    //Clear bottom
                    for (int x = 0; x < image.Width; x++)
                    {
                        for (int y = 1080; y < 1080 + 100; y++)
                        {
                            image[x, y] = new Rgba32(0f, 0f, 0f, 1f);
                        }
                    }

                    //Load JSON data to get the date
                    var      postData     = JsonConvert.DeserializeObject <JArray>(File.ReadAllText(Program.OUTPUT_POSTS + e.node.id + ".json"));
                    double   unixPostTime = (long)postData[0].SelectToken("data").SelectToken("children")[0].SelectToken("data").SelectToken("created_utc");
                    DateTime postTime     = new DateTime(1970, 1, 1, 0, 0, 0).AddHours(-6).AddSeconds(unixPostTime);

                    //Create date string
                    string date = $"{postTime.DayOfWeek.ToString()} {postTime.Month}/{postTime.Day}/{postTime.Year} {postTime.ToShortTimeString()} CST";

                    //Set date on the bottom
                    var   textSize = TextMeasurer.Measure(date, mainFontRendererOptions);
                    float xTextPos = 50 - (textSize.Height / 2);
                    var   pos      = new SixLabors.Primitives.PointF(xTextPos, 1080 + 50 - (textSize.Height / 2));
                    image.Mutate(x => x.DrawText(date, mainFont, Rgba32.White, pos));

                    //Add credit on side
                    textSize = TextMeasurer.Measure(SIDE_TEXT, smallFontRendererOptions);
                    xTextPos = 1920 - xTextPos - textSize.Width;
                    pos      = new SixLabors.Primitives.PointF(xTextPos, 1080 + 50 - (textSize.Height / 2));
                    image.Mutate(x => x.DrawText(SIDE_TEXT, smallFont, Rgba32.Gray, pos));

                    //Save
                    tasks.Add(SaveAsync(image.Clone(), Program.OUTPUT_CANVAS + saved++.ToString() + ".png"));
                }
                Console.Write($"\r[Canvas] Saved {i}/{edges.Count}...         ");
            }

            //Wait for all tasks to finish
            Console.Write("\r[Canvas] Waiting for tasks to finish...");
            Task.WaitAll(tasks.ToArray());

            //Save last image
            SaveAsync(image.Clone(), Program.OUTPUT_CANVAS + saved++.ToString() + ".png").GetAwaiter().GetResult();
        }