Bitmaps aus SVG extrahieren

Ich habe ein paar SVG-Dateien mit Inkscape erstellt, dort Bitmaps eingebettet und später die Original-Bitmaps gelöscht.

Ich möchte jetzt die Bitmap aus den SVGs extrahieren, um die ursprünglichen Bitmaps wiederherzustellen. Ich kann die SVG in Inkscape öffnen, aber das Kopieren der Bitmap kopiert sie verzerrt, wenn die Bitmap nicht unter Beibehaltung des Seitenverhältnisses skaliert wurde. Außerdem kopiert es die Bitmap in der Zielgröße, die größer oder kleiner als die ursprüngliche Bitmap sein kann.

IMHO ist die Bitmap im SVG in Originalauflösung zusammen mit den daran vorgenommenen Änderungen (Größe, Drehung usw.) verfügbar.

Also suche ich ein Tool, das

  • Bitmaps aus SVG-Dateien extrahieren
  • benennt sie automatisch (image0001.jpg und ähnliches ist ok)
  • tun Sie dies automatisch für mehrere Dateien gleichzeitig
  • machen es möglich, das ursprüngliche SVG zu identifizieren, indem Sie die Bitmaps ähnlich wie das SVG benennen oder sie in Verzeichnisse mit dem gleichen Namen wie das SVG usw. ablegen.
  • funktioniert unter Windows
  • ist kostenlos

Ich suche keine Do-it-yourself-Programmierlösung. Ich weiß, dass SVG XML ist und die Daten in <image>Tags enthalten sind, base64-codiert. Ich werde das wahrscheinlich tun, wenn keine anderen Lösungen (getestet usw.) verfügbar sind.

Antworten (1)

Ich habe lange keine Antwort bekommen, also habe ich es endlich in C# implementiert. Sie können die kostenlose Microsoft Visual Studio 2017 Community Edition verwenden .

Es entspricht den Anforderungen:

  • benennt sie automatisch: beginnt bei 0 und erhöht die Zahl
  • mehrere Dateien auf einmal: Als Argument können mehrere Dateien übergeben werden
  • Identifizieren Sie das ursprüngliche SVG durch Benennung: Es verwendet den ursprünglichen SVG-Namen
  • funktioniert unter Windows: ja
  • ist kostenlos: ja
  • Bitmaps aus SVG-Dateien extrahieren: Es funktioniert nicht für alle Bildtypen, im Moment nur für PNGs.

Erstellen Sie eine Konsolenanwendung und erstellen Sie 3 Dateien mit dem folgenden Inhalt.

Datei ExtractBitmapFromSvg.cs:

namespace ExtractBitmapFromSvg
{
    static class ExtractBitmapFromSvg
    {
        static void Main(string[] args)
        {
            for (int i = 0; i < args.Length; i++)
            {
                var svgFile = new SvgFile(args[i]);
                var images = svgFile.GetEmbeddedImages();
                for (var imagenumber = 0; imagenumber < images.Count; imagenumber++)
                {
                    var image = images[imagenumber];
                    image.SaveAs(args[i] + imagenumber + image.Extension);
                }
            }
        }
    }
}

Datei Image.cs

using System;
using System.Collections.Generic;
using System.IO;

namespace ExtractBitmapFromSvg
{
    class Image
    {
        private static readonly Dictionary<string, string> Filetypes = new Dictionary<string, string>();

        static Image()
        {
            Filetypes.Add("image/png", ".png");
        }

        internal Image(string mimeType, string base64Data)
        {
            MimeType = mimeType;
            Data = Convert.FromBase64String(base64Data);
        }

        internal string MimeType;
        internal string Extension => FindExtension(MimeType);

        private static string FindExtension(string mimeType)
        {
            return Filetypes[mimeType];
        }

        internal byte[] Data;

        public void SaveAs(string destination)
        {
            File.WriteAllBytes(destination, Data);
        }
    }
}

Datei SvgFile.cs:

using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using System.Xml.Linq;

namespace ExtractBitmapFromSvg
{
    class SvgFile
    {
        private readonly XDocument xDocument;
        private const string IMAGE = "{http://www.w3.org/2000/svg}image";
        private const string HREF = "{http://www.w3.org/1999/xlink}href";
        readonly Regex regexMimeTypeAndData = new Regex("^data:(.*);base64,(.*)");

        internal SvgFile(string fileName)
        {
            xDocument = XDocument.Load(fileName);
        }

        internal List<Image> GetEmbeddedImages()
        {            
            var result = new List<Image>();
            var xElements = from svg in xDocument.Descendants(IMAGE)
                select svg.Attribute(HREF);
            foreach (var xElement in xElements)
            {
                var match = regexMimeTypeAndData.Match(xElement.Value);
                var mimeType = match.Groups[1].Value;
                var base64Data = match.Groups[2].Value;
                result.Add(new Image(mimeType, base64Data));
            }
            return result;
        }
    }
}