Extraer mapas de bits de SVG

Creé algunos archivos SVG con Inkscape, incrusté mapas de bits allí y luego eliminé los mapas de bits originales.

Ahora me gustaría extraer el mapa de bits de los SVG para recuperar los mapas de bits originales. Puedo abrir el SVG en Inkscape, pero copiar el mapa de bits lo copia de forma distorsionada si el mapa de bits no se escala manteniendo la relación de aspecto. Además, copia el mapa de bits en el tamaño de destino, que puede ser mayor o menor que el mapa de bits original.

En mi humilde opinión, el mapa de bits en el SVG está disponible en resolución original junto con las modificaciones realizadas (tamaño, rotación, etc.).

Así que estoy buscando una herramienta que

  • extraer mapas de bits de archivos SVG
  • los nombra automáticamente (image0001.jpg y similar está bien)
  • haz eso automáticamente para varios archivos a la vez
  • hacer posible identificar el SVG original nombrando los mapas de bits similares al SVG o colocándolos en directorios nombrados como SVG, etc.
  • funciona en Windows
  • es gratis

No estoy buscando una solución de programación de bricolaje. Sé que SVG es XML y los datos están contenidos en <image>etiquetas, codificados en base64. Probablemente lo haré si no hay otras soluciones (probadas, etc.) disponibles.

Respuestas (1)

No obtuve una respuesta durante mucho tiempo, así que finalmente la implementé en C#. Puede utilizar Microsoft Visual Studio 2017 Community Edition de forma gratuita .

Cumple con los requisitos:

  • los nombra automáticamente: comienza en 0 y aumenta el número
  • varios archivos a la vez: se pueden pasar varios archivos como argumento
  • identifique el SVG original nombrándolo: utiliza el nombre SVG original
  • funciona en Windows: sí
  • es gratis: si
  • extraer mapas de bits de archivos SVG: no funcionará para todos los tipos de imágenes, solo PNG por el momento.

Cree una aplicación de consola y cree 3 archivos con el contenido a continuación.

Archivo 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);
                }
            }
        }
    }
}

Imagen de archivo.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);
        }
    }
}

Archivo 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;
        }
    }
}