Пример #1
0
        /// <summary>
        /// Sets the contents of the region to the specified path.
        /// </summary>
        /// <param name="region">The region to set the path into.</param>
        /// <param name="path">The path object.</param>
        /// <param name="usePathBounds">Whether to set the region's new bounds to the bounds of the path itself.</param>
        internal static bool SetPath(this SKRegion region, SKPath path, bool usePathBounds)
        {
            if (usePathBounds && path.GetBounds(out SKRect bounds))
            {
                using SKRegion clip = new SKRegion();

                clip.SetRect(SKRectI.Ceiling(bounds));
                return(region.SetPath(path, clip));
            }
            else
            {
                return(region.SetPath(path));
            }
        }
Пример #2
0
        //Default resolution makes 10 points per line segment
        private bool IsInside(SKPath pInput, SKPath pBoundary)
        {
            var input    = new SKRegion();
            var boundary = new SKRegion();

            input.SetRect(ToIntRect(pInput.Bounds));
            boundary.SetRect(ToIntRect(pBoundary.Bounds));
            input.SetPath(pInput);
            boundary.SetPath(pBoundary);

            var contained = boundary.Contains(input);

            return(contained);
        }
        void OnCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs args)
        {
            SKImageInfo info    = args.Info;
            SKSurface   surface = args.Surface;
            SKCanvas    canvas  = surface.Canvas;

            canvas.Clear();

            int radius = 10;

            // Create circular path
            using (SKPath circlePath = new SKPath())
            {
                circlePath.AddCircle(0, 0, radius);

                // Create circular region
                using (SKRegion circleRegion = new SKRegion())
                {
                    circleRegion.SetRect(new SKRectI(-radius, -radius, radius, radius));
                    circleRegion.SetPath(circlePath);

                    // Set transform to move it to center and scale up
                    canvas.Translate(info.Width / 2, info.Height / 2);
                    canvas.Scale(Math.Min(info.Width / 2, info.Height / 2) / radius);

                    // Fill region
                    using (SKPaint fillPaint = new SKPaint())
                    {
                        fillPaint.Style = SKPaintStyle.Fill;
                        fillPaint.Color = SKColors.Orange;

                        canvas.DrawRegion(circleRegion, fillPaint);
                    }

                    // Stroke path for comparison
                    using (SKPaint strokePaint = new SKPaint())
                    {
                        strokePaint.Style       = SKPaintStyle.Stroke;
                        strokePaint.Color       = SKColors.Blue;
                        strokePaint.StrokeWidth = 0.1f;

                        canvas.DrawPath(circlePath, strokePaint);
                    }
                }
            }
        }
Пример #4
0
        public void SetPathWithClipDoesCreatesCorrectRegion()
        {
            var clipRect = new SKRectI(25, 25, 50, 50);
            var clip     = new SKRegion();

            clip.SetRect(clipRect);

            var rect = new SKRectI(10, 20, 30, 40);
            var path = new SKPath();

            path.AddRect(rect);

            var region     = new SKRegion();
            var isNonEmpty = region.SetPath(path, clip);

            Assert.IsTrue(isNonEmpty);
            Assert.AreEqual(SKRectI.Intersect(clipRect, rect), region.Bounds);
        }
Пример #5
0
        void DisplayClipOp(SKCanvas canvas, SKRect rect, SKRegionOperation regionOp)
        {
            float textSize = textPaint.TextSize;

            canvas.DrawText(regionOp.ToString(), rect.MidX, rect.Top + textSize, textPaint);
            rect.Top += textSize;

            float radius  = 0.9f * Math.Min(rect.Width / 3, rect.Height / 2);
            float xCenter = rect.MidX;
            float yCenter = rect.MidY;

            SKRectI recti = new SKRectI((int)rect.Left, (int)rect.Top,
                                        (int)rect.Right, (int)rect.Bottom);

            using (SKRegion wholeRectRegion = new SKRegion())
            {
                wholeRectRegion.SetRect(recti);

                using (SKRegion region1 = new SKRegion(wholeRectRegion))
                    using (SKRegion region2 = new SKRegion(wholeRectRegion))
                    {
                        using (SKPath path1 = new SKPath())
                        {
                            path1.AddCircle(xCenter - radius / 2, yCenter, radius);
                            region1.SetPath(path1);
                        }

                        using (SKPath path2 = new SKPath())
                        {
                            path2.AddCircle(xCenter + radius / 2, yCenter, radius);
                            region2.SetPath(path2);
                        }

                        region1.Op(region2, regionOp);

                        canvas.Save();
                        canvas.ClipRegion(region1);
                        canvas.DrawPaint(fillPaint);
                        canvas.Restore();
                    }
            }
        }
        /// <summary>
        /// Process image pipeline
        /// <para>Region THEN Size THEN Rotation THEN Quality THEN Format</para>
        /// </summary>
        /// <param name="imageUri">The <see cref="Uri"/> of the source image</param>
        /// <param name="request">The parsed and validated IIIF Image API request</param>
        /// <param name="quality">Image output encoding quality settings</param>
        /// <param name="allowSizeAboveFull">Allow output image dimensions to exceed that of the source image</param>
        /// <param name="pdfMetadata">Optional PDF metadata fields</param>
        /// <returns></returns>
        public async Task <Stream> ProcessImage(Uri imageUri, ImageRequest request, Conf.ImageQuality quality, bool allowSizeAboveFull, Conf.PdfMetadata pdfMetadata)
        {
            var encodingStrategy = GetEncodingStrategy(request.Format);

            if (encodingStrategy == EncodingStrategy.Unknown)
            {
                throw new ArgumentException("Unsupported format", "format");
            }

            var loader = new ImageLoader {
                HttpClient = HttpClient, Log = Log
            };

            (var state, var imageRegion) = await loader.ExtractRegion(imageUri, request, allowSizeAboveFull, quality);

            using (imageRegion)
            {
                var expectedWidth  = state.OutputWidth;
                var expectedHeight = state.OutputHeight;
                var alphaType      = request.Quality == ImageQuality.bitonal ? SKAlphaType.Opaque : SKAlphaType.Premul;

                (var angle, var originX, var originY, var newImgWidth, var newImgHeight) = Rotate(expectedWidth, expectedHeight, request.Rotation.Degrees);

                using (var surface = SKSurface.Create(width: newImgWidth, height: newImgHeight, colorType: SKImageInfo.PlatformColorType, alphaType: alphaType))
                    using (var canvas = surface.Canvas)
                        using (var region = new SKRegion())
                        {
                            // If the rotation parameter includes mirroring ("!"), the mirroring is applied before the rotation.
                            if (request.Rotation.Mirror)
                            {
                                canvas.Translate(newImgWidth, 0);
                                canvas.Scale(-1, 1);
                            }

                            canvas.Translate(originX, originY);
                            canvas.RotateDegrees(angle, 0, 0);

                            // reset clip rects to rotated boundaries
                            region.SetRect(new SKRectI(0 - (int)originX, 0 - (int)originY, newImgWidth, newImgHeight));
                            canvas.ClipRegion(region);

                            // quality
                            if (request.Quality == ImageQuality.gray || request.Quality == ImageQuality.bitonal)
                            {
                                var contrast = request.Quality == ImageQuality.gray ? 0.1f : 1f;
                                using (var cf = SKColorFilter.CreateHighContrast(true, SKHighContrastConfigInvertStyle.NoInvert, contrast))
                                    using (var paint = new SKPaint())
                                    {
                                        paint.FilterQuality = SKFilterQuality.High;
                                        paint.ColorFilter   = cf;

                                        canvas.DrawImage(imageRegion, new SKRect(0, 0, expectedWidth, expectedHeight), paint);
                                    }
                            }
                            else
                            {
                                using (var paint = new SKPaint())
                                {
                                    paint.FilterQuality = SKFilterQuality.High;
                                    canvas.DrawImage(imageRegion, new SKRect(0, 0, expectedWidth, expectedHeight), paint);
                                }
                            }

                            return(Encode(surface,
                                          expectedWidth,
                                          expectedHeight,
                                          encodingStrategy,
                                          request.Format,
                                          quality.GetOutputFormatQuality(request.Format),
                                          pdfMetadata,
                                          state.HorizontalResolution,
                                          state.VerticalResolution));
                        }
            }
        }
        void OnCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs args)
        {
            SKImageInfo info    = args.Info;
            SKSurface   surface = args.Surface;
            SKCanvas    canvas  = surface.Canvas;

            canvas.Clear();

            float xCenter = info.Width / 2;
            float yCenter = info.Height / 2;
            float radius  = 0.24f * Math.Min(info.Width, info.Height);

            using (SKRegion wholeScreenRegion = new SKRegion())
            {
                wholeScreenRegion.SetRect(new SKRectI(0, 0, info.Width, info.Height));

                using (SKRegion leftRegion = new SKRegion(wholeScreenRegion))
                    using (SKRegion rightRegion = new SKRegion(wholeScreenRegion))
                        using (SKRegion topRegion = new SKRegion(wholeScreenRegion))
                            using (SKRegion bottomRegion = new SKRegion(wholeScreenRegion))
                            {
                                using (SKPath circlePath = new SKPath())
                                {
                                    // Make basic circle path
                                    circlePath.AddCircle(xCenter, yCenter, radius);

                                    // Left leaf
                                    circlePath.Transform(SKMatrix.MakeTranslation(-radius, 0));
                                    leftRegion.SetPath(circlePath);

                                    // Right leaf
                                    circlePath.Transform(SKMatrix.MakeTranslation(2 * radius, 0));
                                    rightRegion.SetPath(circlePath);

                                    // Make union of right with left
                                    leftRegion.Op(rightRegion, SKRegionOperation.Union);

                                    // Top leaf
                                    circlePath.Transform(SKMatrix.MakeTranslation(-radius, -radius));
                                    topRegion.SetPath(circlePath);

                                    // Combine with bottom leaf
                                    circlePath.Transform(SKMatrix.MakeTranslation(0, 2 * radius));
                                    bottomRegion.SetPath(circlePath);

                                    // Make union of top with bottom
                                    bottomRegion.Op(topRegion, SKRegionOperation.Union);

                                    // Exclusive-OR left and right with top and bottom
                                    leftRegion.Op(bottomRegion, SKRegionOperation.XOR);

                                    // Set that as clip region
                                    canvas.ClipRegion(leftRegion);

                                    // Set transform for drawing lines from center
                                    canvas.Translate(xCenter, yCenter);

                                    // Draw 360 lines
                                    for (double angle = 0; angle < 360; angle++)
                                    {
                                        float x = 2 * radius * (float)Math.Cos(Math.PI * angle / 180);
                                        float y = 2 * radius * (float)Math.Sin(Math.PI * angle / 180);

                                        using (SKPaint strokePaint = new SKPaint())
                                        {
                                            strokePaint.Color       = SKColors.Green;
                                            strokePaint.StrokeWidth = 2;

                                            canvas.DrawLine(0, 0, x, y, strokePaint);
                                        }
                                    }
                                }
                            }
            }
        }