LOGO OA教程 ERP教程 模切知识交流 PMS教程 CRM教程 开发文档 其他文档  
 
网站管理员

C# WinForm中使用SVG.NET库完整指南

admin
2024年11月12日 13:33 本文热度 286

SVG.NET是一个强大的开源库,专门用于在.NET应用程序中处理SVG(Scalable Vector Graphics)文件。本文将详细介绍如何在WinForm应用程序中使用SVG.NET库来显示和操作SVG图片。

环境准备

安装SVG.NET库

在Visual Studio中,通过NuGet包管理器安装Svg包:

Install-Package Svg

或在包管理器控制台中执行:

dotnet add package Svg

添加必要的引用

using Svg;using System.Drawing;using System.Drawing.Imaging;

基础使用

加载并显示SVG

private void btnLoad_Click(object sender, EventArgs e){    var svgDocument = SvgDocument.Open("1.svg");    var bitmap = svgDocument.Draw();    pictureBox1.Image = bitmap;}

1.svg文件

<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"[]><svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="64px" height="64px" viewBox="0 0 125.921 121.105" enable-background="new 0 0 125.921 121.105" xml:space="preserve"><g id="Group_OutletPort">     <linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="119.3706" y1="-412.0227" x2="119.3706" y2="-361.6145" gradientTransform="matrix(1 0 0 -1 0 -360.895)">    <stop offset="0" style="stop-color:#4D4D4D" />    <stop offset="0.21" style="stop-color:#717171" />    <stop offset="0.54" style="stop-color:#A6A6A6" />    <stop offset="0.64" style="stop-color:#9F9F9F" />    <stop offset="0.79" style="stop-color:#8C8C8C" />    <stop offset="0.97" style="stop-color:#6D6D6D" />    <stop offset="1" style="stop-color:#666666" />  </linearGradient>  <rect x="112.821" y="0.719" fill="url(#SVGID_1_)" stroke="#B3B3B3" stroke-width="0.5" width="13.101" height="50.408" />     <linearGradient id="SVGID_2_" gradientUnits="userSpaceOnUse" x1="83.0708" y1="76.9197" x2="83.0708" y2="115.9207" gradientTransform="matrix(1 0 0 -1 0 122.105)">    <stop offset="0" style="stop-color:#4D4D4D" />    <stop offset="0.52" style="stop-color:#B2B2B2" />    <stop offset="1" style="stop-color:#666666" />  </linearGradient>  <polyline fill="url(#SVGID_2_)" points="53.235,6.184 112.907,6.184 112.907,45.185 102.517,45.185  " /></g><g id="Group_Legs">     <linearGradient id="SVGID_3_" gradientUnits="userSpaceOnUse" x1="52.5283" y1="1094.1335" x2="52.5283" y2="1058.2527" gradientTransform="matrix(1 0 0 1 0 -973.75)">    <stop offset="0" style="stop-color:#999999" />    <stop offset="1" style="stop-color:#666666" />  </linearGradient>  <path fill="url(#SVGID_3_)" stroke="#999999" stroke-width="0.396" d="M11.321,120.384l10.254-35.881h61.908l10.252,35.881H72.966   L52.462,89.497l-20.769,30.887H11.321z" /></g><g id="Group_LegBase">  <path fill="#999999" stroke="#B3B3B3" stroke-width="0.5" d="M0.76,115.851h37.533v5.254H0.76V115.851z" />  <path fill="#999999" stroke="#B3B3B3" stroke-width="0.5" d="M66.603,115.851h37.929v5.254H66.603V115.851L66.603,115.851z" /></g><g id="Group_PumpBody">     <radialGradient id="SVGID_4_" cx="126.48" cy="837.1521" r="51.5659" gradientTransform="matrix(0.9999 0.0069 -0.0069 0.9999 -67.9976 -780.2224)" gradientUnits="userSpaceOnUse">    <stop offset="0.18" style="stop-color:#333333" />    <stop offset="0.26" style="stop-color:#383838" />    <stop offset="0.35" style="stop-color:#454545" />    <stop offset="0.44" style="stop-color:#5C5C5C" />    <stop offset="0.54" style="stop-color:#7B7B7B" />    <stop offset="0.64" style="stop-color:#A4A4A4" />    <stop offset="0.72" style="stop-color:#CCCCCC" />    <stop offset="0.81" style="stop-color:#B1B1B1" />    <stop offset="0.99" style="stop-color:#6B6B6B" />    <stop offset="1" style="stop-color:#666666" />  </radialGradient>  <path fill="url(#SVGID_4_)" d="M53.047,6.158c28.477,0.196,51.402,23.439,51.207,51.917c-0.195,28.475-23.438,51.398-51.914,51.204   C23.862,109.086,0.938,85.841,1.133,57.364C1.326,28.889,24.573,5.963,53.047,6.158z" /></g><g id="Group_CenterShade">     <radialGradient id="SVGID_5_" cx="52.4468" cy="-418.7268" r="27.2441" gradientTransform="matrix(1 0 0 -1 0 -360.895)" gradientUnits="userSpaceOnUse">    <stop offset="0" style="stop-color:#000000" />    <stop offset="1" style="stop-color:#333333" />  </radialGradient>  <path fill="url(#SVGID_5_)" d="M38.399,81.168C25.508,73.407,21.35,56.67,29.111,43.78c7.762-12.888,24.502-17.045,37.385-9.285   c12.891,7.761,17.047,24.498,9.289,37.393C68.021,84.769,51.286,88.928,38.399,81.168z" /></g><g id="Group_Impeller">     <linearGradient id="SVGID_6_" gradientUnits="userSpaceOnUse" x1="101.9819" y1="125.5398" x2="106.1411" y2="125.5342" gradientTransform="matrix(0.9889 0.1484 0.1484 -0.9889 -69.6528 166.4384)">    <stop offset="0.01" style="stop-color:#666666" />    <stop offset="0.51" style="stop-color:#B8B8B8" />    <stop offset="1" style="stop-color:#666666" />  </linearGradient>  <path fill="url(#SVGID_6_)" d="M51.014,77.055c-0.642,4.14-2.024,7.351-3.166,7.187c-1.139-0.165-1.545-3.651-0.902-7.789   l0.014-0.081l5.874-37.983c0.64-4.139,1.986-7.314,3.125-7.149c1.142,0.163,1.507,3.623,0.866,7.76L51.014,77.055z" />     <linearGradient id="SVGID_7_" gradientUnits="userSpaceOnUse" x1="-277.9653" y1="21.0618" x2="-273.8071" y2="21.0562" gradientTransform="matrix(0.6317 -0.7752 -0.7752 -0.6317 243.0495 -142.3917)">    <stop offset="0.01" style="stop-color:#666666" />    <stop offset="0.51" style="stop-color:#B8B8B8" />    <stop offset="1" style="stop-color:#666666" />  </linearGradient>  <path fill="url(#SVGID_7_)" d="M68.625,68.765c3.234,2.659,5.291,5.485,4.57,6.387c-0.724,0.895-3.931-0.533-7.162-3.193   l-0.063-0.053L36.284,47.493c-3.234-2.66-5.28-5.437-4.559-6.333c0.722-0.898,3.884,0.55,7.117,3.21L68.625,68.765z" />     <linearGradient id="SVGID_8_" gradientUnits="userSpaceOnUse" x1="216.7651" y1="433.1179" x2="220.9233" y2="433.1123" gradientTransform="matrix(0.4225 0.9064 0.9064 -0.4225 -432.8737 42.0522)">    <stop offset="0.01" style="stop-color:#666666" />    <stop offset="0.51" style="stop-color:#B8B8B8" />    <stop offset="1" style="stop-color:#666666" />  </linearGradient>  <path fill="url(#SVGID_8_)" d="M35.58,67.368c-3.803,1.752-7.245,2.373-7.739,1.332c-0.491-1.041,2.193-3.306,5.994-5.057   l0.076-0.033L68.82,47.527c3.805-1.752,7.195-2.384,7.686-1.345c0.494,1.041-2.188,3.258-5.99,5.008L35.58,67.368z" />     <radialGradient id="SVGID_9_" cx="51.9766" cy="64.4246" r="6.541" gradientTransform="matrix(1 0 0 -1 0 122.105)" gradientUnits="userSpaceOnUse">    <stop offset="0" style="stop-color:#B8B8B8" />    <stop offset="0.47" style="stop-color:#B6B6B6" />    <stop offset="0.64" style="stop-color:#AFAFAF" />    <stop offset="0.76" style="stop-color:#A3A3A3" />    <stop offset="0.85" style="stop-color:#929292" />    <stop offset="0.94" style="stop-color:#7D7D7D" />    <stop offset="1" style="stop-color:#666666" />  </radialGradient>  <path fill="url(#SVGID_9_)" d="M53.274,51.269c3.543,0.718,5.829,4.168,5.11,7.709c-0.717,3.544-4.167,5.83-7.71,5.113   c-3.536-0.719-5.824-4.171-5.105-7.711C46.284,52.844,49.739,50.552,53.274,51.269z" /></g></svg>

高级功能

SVG缩放控制

public partial class Form1 : Form{    private SvgDocument svgDoc;    private float currentScale = 1.0f;    private PictureBox pictureBox;    private TrackBar scaleTrackBar;    private Label scaleLabel;    private int originalWidth;    private int originalHeight;
   public Form1()    {        InitializeComponent();
       // 创建PictureBox用于显示SVG          pictureBox = new PictureBox        {            Dock = DockStyle.Fill,            SizeMode = PictureBoxSizeMode.Normal, // 更改为Normal以便更好地控制缩放              BackColor = Color.White        };
       // 创建TrackBar用于控制缩放          scaleTrackBar = new TrackBar        {            Dock = DockStyle.Bottom,            Minimum = 10,  // 10% 的缩放              Maximum = 400, // 400% 的缩放              Value = 100,   // 默认100%              TickFrequency = 10        };        scaleTrackBar.ValueChanged += ScaleTrackBar_ValueChanged;
       // 创建标签显示当前缩放比例          scaleLabel = new Label        {            Text = "缩放: 100%",            Dock = DockStyle.Bottom,            TextAlign = ContentAlignment.MiddleCenter,            Height = 30        };
       // 添加控件到窗体          this.Controls.Add(pictureBox);        this.Controls.Add(scaleLabel);        this.Controls.Add(scaleTrackBar);
       LoadSvg();    }
   private void LoadSvg()    {        try        {            // 加载SVG文件              svgDoc = SvgDocument.Open("1.svg");
           // 保存原始尺寸              originalWidth = (int)svgDoc.Width.Value;            originalHeight = (int)svgDoc.Height.Value;
           // 初始显示              UpdateSvgDisplay();        }        catch (Exception ex)        {            MessageBox.Show($"加载SVG文件时出错: {ex.Message}");        }    }
   private void ScaleTrackBar_ValueChanged(object sender, EventArgs e)    {        currentScale = scaleTrackBar.Value / 100f;        scaleLabel.Text = $"缩放: {scaleTrackBar.Value}%";        UpdateSvgDisplay();    }
   private void UpdateSvgDisplay()    {        if (svgDoc != null)        {            try            {                // 计算缩放后的尺寸                  int scaledWidth = (int)(originalWidth * currentScale);                int scaledHeight = (int)(originalHeight * currentScale);
               // 创建新的位图                  var bitmap = new Bitmap(scaledWidth, scaledHeight);
               using (Graphics graphics = Graphics.FromImage(bitmap))                {                    // 设置高质量绘制                      graphics.SmoothingMode = SmoothingMode.HighQuality;                    graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;                    graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;                    graphics.Clear(Color.White);
                   // 创建缩放矩阵                      graphics.ScaleTransform(currentScale, currentScale);
                   // 绘制SVG                      svgDoc.Draw(graphics, new SizeF(originalWidth, originalHeight));                }
               // 更新PictureBox                  if (pictureBox.Image != null)                {                    pictureBox.Image.Dispose();                }                pictureBox.Image = bitmap;                pictureBox.Refresh();            }            catch (Exception ex)            {                MessageBox.Show($"更新SVG显示时出错: {ex.Message}");            }        }    }
   protected override void OnFormClosing(FormClosingEventArgs e)    {        base.OnFormClosing(e);        // 清理资源          if (pictureBox.Image != null)        {            pictureBox.Image.Dispose();        }    }}

SVG颜色修改

SvgColorManager 类

public class SvgColorManager{    private SvgDocument svgDocument;    private PictureBox pictureBox;    private Dictionary<SvgVisualElement, ColorInfo> originalColors; // 修改存储结构  
   // 用于存储颜色信息的类      private class ColorInfo    {        public SvgPaintServer Fill { get; set; }        public SvgPaintServer Stroke { get; set; }        public float? StrokeWidth { get; set; }    }
   public SvgColorManager(PictureBox pictureBox)    {        this.pictureBox = pictureBox ?? throw new ArgumentNullException(nameof(pictureBox));        this.originalColors = new Dictionary<SvgVisualElement, ColorInfo>();    }
   public bool LoadSvg(string filePath)    {        try        {            svgDocument = SvgDocument.Open(filePath);            StoreOriginalColors();            UpdateDisplay();            return true;        }        catch (Exception ex)        {            MessageBox.Show($"加载SVG文件失败: {ex.Message}");            return false;        }    }
   private void StoreOriginalColors()    {        originalColors.Clear();        foreach (var element in svgDocument.Descendants())        {            if (element is SvgVisualElement visual)            {                // 存储每个元素的原始颜色信息                  originalColors[visual] = new ColorInfo                {                    Fill = visual.Fill,                    Stroke = visual.Stroke,                    StrokeWidth = visual.StrokeWidth                };            }        }    }
   public void ChangeElementColor(Color newColor, Type elementType = null)    {        if (svgDocument == null) return;
       foreach (var element in svgDocument.Descendants())        {            if (elementType != null && element.GetType() != elementType) continue;
           if (element is SvgVisualElement visual)            {                visual.Fill = new SvgColourServer(newColor);            }        }
       UpdateDisplay();    }
   public void ChangeStrokeColor(Color newColor, float? strokeWidth = null)    {        if (svgDocument == null) return;
       foreach (var element in svgDocument.Descendants())        {            if (element is SvgVisualElement visual)            {                visual.Stroke = new SvgColourServer(newColor);                if (strokeWidth.HasValue)                {                    visual.StrokeWidth = strokeWidth.Value;                }            }        }
       UpdateDisplay();    }
   public void RestoreOriginalColors()    {        if (svgDocument == null) return;
       foreach (var element in svgDocument.Descendants())        {            if (element is SvgVisualElement visual && originalColors.ContainsKey(visual))            {                var originalColor = originalColors[visual];                visual.Fill = originalColor.Fill;                visual.Stroke = originalColor.Stroke;                if (originalColor.StrokeWidth.HasValue)                {                    visual.StrokeWidth = originalColor.StrokeWidth.Value;                }            }        }
       UpdateDisplay();    }
   public void ChangeElementColorById(string elementId, Color fillColor, Color? strokeColor = null)    {        if (svgDocument == null) return;
       var element = svgDocument.Descendants()            .FirstOrDefault(e => e is SvgVisualElement && e.ID == elementId) as SvgVisualElement;
       if (element != null)        {            element.Fill = new SvgColourServer(fillColor);            if (strokeColor.HasValue)            {                element.Stroke = new SvgColourServer(strokeColor.Value);            }            UpdateDisplay();        }    }
   private void UpdateDisplay()    {        try        {            if (pictureBox.Image != null)            {                var oldImage = pictureBox.Image;                pictureBox.Image = svgDocument.Draw();                oldImage.Dispose();            }            else            {                pictureBox.Image = svgDocument.Draw();            }            pictureBox.Refresh();        }        catch (Exception ex)        {            MessageBox.Show($"更新显示失败: {ex.Message}");        }    }
   public bool SaveSvg(string filePath)    {        try        {            svgDocument.Write(filePath);            return true;        }        catch (Exception ex)        {            MessageBox.Show($"保存SVG文件失败: {ex.Message}");            return false;        }    }
   public void Dispose()    {        if (pictureBox?.Image != null)        {            pictureBox.Image.Dispose();            pictureBox.Image = null;        }        originalColors.Clear();        pictureBox = null;        svgDocument = null;    }}

public partial class Form2 : Form{    private SvgColorManager colorManager;    public Form2()    {        InitializeComponent();        // 初始化ColorManager          colorManager = new SvgColorManager(pictureBox1);
       // 加载SVG文件          colorManager.LoadSvg("1.svg"); // 确保文件存在      }
   private void btnChangeFill_Click(object sender, EventArgs e)    {        using (ColorDialog colorDialog = new ColorDialog())        {            if (colorDialog.ShowDialog() == DialogResult.OK)            {                colorManager.ChangeElementColor(colorDialog.Color);            }        }    }
   private void btnChangeStroke_Click(object sender, EventArgs e)    {        using (ColorDialog colorDialog = new ColorDialog())        {            if (colorDialog.ShowDialog() == DialogResult.OK)            {                colorManager.ChangeStrokeColor(colorDialog.Color);            }        }    }
   private void btnRestore_Click(object sender, EventArgs e)    {        colorManager.RestoreOriginalColors();    }}

SVG元素操作

using Svg.Transforms;using Svg;using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;
namespace AppSvg01{    public class SvgElementManager    {        private SvgDocument svgDocument;        private PictureBox pictureBox;
       public SvgElementManager(PictureBox pictureBox)        {            this.pictureBox = pictureBox ?? throw new ArgumentNullException(nameof(pictureBox));        }
       /// <summary>          /// 加载SVG文件          /// </summary>          public bool LoadSvg(string filePath)        {            try            {                svgDocument = SvgDocument.Open(filePath);                UpdateDisplay();                return true;            }            catch (Exception ex)            {                MessageBox.Show($"加载SVG文件失败: {ex.Message}");                return false;            }        }
       /// <summary>          /// 修改特定元素          /// </summary>          public void ModifyElement(string elementId, float opacity = 1.0f, float rotation = 0,            float? scaleX = null, float? scaleY = null, Color? fillColor = null)        {            if (svgDocument == null) return;
           var element = svgDocument.GetElementById(elementId);            if (element != null && element is SvgVisualElement visual)            {                // 设置透明度                  visual.Opacity = opacity;
               // 创建变换集合                  if (visual.Transforms == null)                    visual.Transforms = new SvgTransformCollection();                else                    visual.Transforms.Clear();
               // 添加旋转                  if (rotation != 0)                {                    visual.Transforms.Add(new SvgRotate(rotation));                }
               // 添加缩放                  if (scaleX.HasValue || scaleY.HasValue)                {                    visual.Transforms.Add(new SvgScale(                        scaleX ?? 1.0f,                        scaleY ?? scaleX ?? 1.0f                    ));                }
               // 设置填充颜色                  if (fillColor.HasValue)                {                    visual.Fill = new SvgColourServer(fillColor.Value);                }
               UpdateDisplay();            }        }
       /// <summary>          /// 添加新元素          /// </summary>          public void AddElement(SvgElementType elementType, float x, float y, float width, float height,            Color fillColor, Color? strokeColor = null, float strokeWidth = 1)        {            if (svgDocument == null) return;
           SvgVisualElement element = null;
           switch (elementType)            {                case SvgElementType.Rectangle:                    element = new SvgRectangle                    {                        X = new SvgUnit(x),                        Y = new SvgUnit(y),                        Width = new SvgUnit(width),                        Height = new SvgUnit(height)                    };                    break;
               case SvgElementType.Circle:                    element = new SvgCircle                    {                        CenterX = new SvgUnit(x + width / 2),                        CenterY = new SvgUnit(y + height / 2),                        Radius = new SvgUnit(Math.Min(width, height) / 2)                    };                    break;
               case SvgElementType.Ellipse:                    element = new SvgEllipse                    {                        CenterX = new SvgUnit(x + width / 2),                        CenterY = new SvgUnit(y + height / 2),                        RadiusX = new SvgUnit(width / 2),                        RadiusY = new SvgUnit(height / 2)                    };                    break;
               case SvgElementType.Line:                    element = new SvgLine                    {                        StartX = new SvgUnit(x),                        StartY = new SvgUnit(y),                        EndX = new SvgUnit(x + width),                        EndY = new SvgUnit(y + height)                    };                    break;            }
           if (element != null)            {                element.Fill = new SvgColourServer(fillColor);                if (strokeColor.HasValue)                {                    element.Stroke = new SvgColourServer(strokeColor.Value);                    element.StrokeWidth = strokeWidth;                }
               svgDocument.Children.Add(element);                UpdateDisplay();            }        }
       /// <summary>          /// 删除元素          /// </summary>          public void RemoveElement(string elementId)        {            if (svgDocument == null) return;
           var element = svgDocument.GetElementById(elementId);            if (element != null)            {                element.Parent?.Children.Remove(element);                UpdateDisplay();            }        }
       /// <summary>          /// 移动元素          /// </summary>          public void MoveElement(string elementId, float deltaX, float deltaY)        {            if (svgDocument == null) return;
           var element = svgDocument.GetElementById(elementId);            if (element is SvgVisualElement visual)            {                if (visual.Transforms == null)                    visual.Transforms = new SvgTransformCollection();
               visual.Transforms.Add(new SvgTranslate(deltaX, deltaY));                UpdateDisplay();            }        }
       /// <summary>          /// 更新显示          /// </summary>          private void UpdateDisplay()        {            try            {                if (pictureBox.Image != null)                {                    var oldImage = pictureBox.Image;                    pictureBox.Image = svgDocument.Draw();                    oldImage.Dispose();                }                else                {                    pictureBox.Image = svgDocument.Draw();                }                pictureBox.Refresh();            }            catch (Exception ex)            {                MessageBox.Show($"更新显示失败: {ex.Message}");            }        }
       /// <summary>          /// 清理资源          /// </summary>          public void Dispose()        {            pictureBox.Image?.Dispose();            pictureBox = null;            svgDocument = null;        }    }
   // SVG元素类型枚举      public enum SvgElementType    {        Rectangle,        Circle,        Ellipse,        Line    }}

总结

使用SVG.NET库在WinForm中处理SVG文件是一个强大而灵活的解决方案。通过本文提供的示例和最佳实践,开发者可以轻松实现SVG文件的加载、显示、缩放和颜色修改等功能。记住要注意性能优化和资源管理,以确保应用程序的稳定性和效率。


该文章在 2024/11/13 14:56:22 编辑过
关键字查询
相关文章
正在查询...
点晴ERP是一款针对中小制造业的专业生产管理软件系统,系统成熟度和易用性得到了国内大量中小企业的青睐。
点晴PMS码头管理系统主要针对港口码头集装箱与散货日常运作、调度、堆场、车队、财务费用、相关报表等业务管理,结合码头的业务特点,围绕调度、堆场作业而开发的。集技术的先进性、管理的有效性于一体,是物流码头及其他港口类企业的高效ERP管理信息系统。
点晴WMS仓储管理系统提供了货物产品管理,销售管理,采购管理,仓储管理,仓库管理,保质期管理,货位管理,库位管理,生产管理,WMS管理系统,标签打印,条形码,二维码管理,批号管理软件。
点晴免费OA是一款软件和通用服务都免费,不限功能、不限时间、不限用户的免费OA协同办公管理系统。
Copyright 2010-2024 ClickSun All Rights Reserved