SvgToGrayscale.cs
- //
- // This code is part of Document Solutions for Imaging demos.
- // Copyright (c) MESCIUS inc. All rights reserved.
- //
- using System;
- using System.IO;
- using System.Drawing;
- using System.Collections.Generic;
- using System.Linq;
- using System.Numerics;
- using GrapeCity.Documents.Drawing;
- using GrapeCity.Documents.Text;
- using GrapeCity.Documents.Imaging;
- using GrapeCity.Documents.Svg;
- using GCTEXT = GrapeCity.Documents.Text;
- using GCDRAW = GrapeCity.Documents.Drawing;
- using DsImagingWeb.Demos.Common;
-
- namespace DsImagingWeb.Demos
- {
- // This sample is similar to SvgClipArt, but after loading each SVG image
- // it converts all strokes and fills in it to grayscale.
- //
- // The SVG clip art used in this sample is from freesvg.org.
- public class SvgToGrayscale
- {
- void ToGrayscale(SvgElementCollection elements)
- {
- foreach (var el in elements)
- {
- if (el is SvgGraphicsElement elg)
- {
- elg.Stroke = PaintToGrayscale(elg.Stroke);
- elg.Fill = PaintToGrayscale(elg.Fill);
- }
- ToGrayscale(el.Children);
- }
- }
-
- // Simplified conversion of an SvgPaint to grayscale
- // (Y formula from https://goodcalculators.com/rgb-to-grayscale-conversion-calculator/):
- SvgPaint PaintToGrayscale(SvgPaint src)
- {
- if (src == null)
- return null;
- else if (src.PaintType == SvgPaintType.Color)
- {
- var rgb = src.Color.Rgb;
- var Y = (int)Math.Round(0.299 * rgb.R + 0.587 * rgb.G + 0.114 * rgb.B);
- return new SvgPaint(Color.FromArgb(Y, Y, Y));
- }
- else
- {
- return new SvgPaint(Color.Gray);
- }
- }
-
- // Main entry point.
- public GcBitmap GenerateImage(Size pixelSize, float dpi, bool opaque, string[] sampleParams = null)
- {
- const int rows = 4;
- const int cols = 4;
- float margin = dpi / 2;
- float sMargin = margin / 4;
-
- // Load images from the resources folder:
- var fnames = new List<string>(Directory.GetFiles(Path.Combine("Resources", "SvgClipArt"), "*", SearchOption.AllDirectories));
- fnames.Shuffle();
- var images = new List<(string, GcSvgDocument)>();
- foreach (var fname in fnames.Take(rows * cols))
- {
- var svg = GcSvgDocument.FromFile(fname);
- ToGrayscale(svg.RootSvg.Children);
- images.Add((Path.GetFileName(fname), svg));
- }
-
- // Font and format for captions:
- var font = GCTEXT.Font.FromFile(Path.Combine("Resources", "Fonts", "segoeui.ttf"));
- var tf = new TextFormat() { Font = font, FontSize = sMargin * 0.65f };
-
- // Set up a 4x4 layout grid:
- float gapx = margin / 4, gapy = gapx;
- float sWidth = (pixelSize.Width - margin * 2 + gapx) / cols;
- float sHeight = (pixelSize.Height - margin * 2 + gapy) / rows;
- if (sWidth > sHeight)
- {
- gapx += sWidth - sHeight;
- sWidth = sHeight;
- }
- else
- {
- gapy += sHeight - sWidth;
- sHeight = sWidth;
- }
- var ip = new PointF(margin, margin);
-
- // Resulting bitmap:
- var bmp = new GcBitmap(pixelSize.Width, pixelSize.Height, opaque, dpi, dpi);
- // Render all images within the grid, adding new pages as needed:
- using var g = bmp.CreateGraphics(Color.White);
- for (int i = 0; i < images.Count(); ++i)
- {
- // Draw border around image:
- var rect = new RectangleF(ip, new SizeF(sWidth - gapx, sHeight - gapy));
- g.FillRectangle(rect, Color.LightGray);
- g.DrawRectangle(rect, Color.Black, 0.5f);
- rect.Inflate(-sMargin, -sMargin);
-
- // Draw the SVG:
- var svg = images[i].Item2;
- var s = svg.GetIntrinsicSize(SvgLengthUnits.Points);
- if (s.Width > 0 && s.Height > 0)
- {
- // If image proportions are different from our target rectangle,
- // we resize the rectangle centering the image in it:
- var qSrc = s.Width / s.Height;
- var qTgt = rect.Width / rect.Height;
- if (qSrc < qTgt)
- rect.Inflate(rect.Width * (qSrc / qTgt - 1) / 2, 0);
- else if (qSrc > qTgt)
- rect.Inflate(0, rect.Height * (qTgt / qSrc - 1) / 2);
- }
- // Render the SVG:
- g.DrawSvg(svg, rect);
-
- // Print image file name as caption in the bottom slide margin:
- g.DrawString(Path.GetFileName(images[i].Item1), tf,
- new RectangleF(rect.X, rect.Bottom, rect.Width, sMargin),
- TextAlignment.Center, ParagraphAlignment.Near, false);
- ip.X += sWidth;
- if (ip.X + sWidth > pixelSize.Width && i < images.Count() - 1)
- {
- ip.X = margin;
- ip.Y += sHeight;
- }
- }
- // Dispose images after saving the result:
- images.ForEach(t_ => t_.Item2.Dispose());
- // Done:
- return bmp;
- }
- }
- }
-