Я создал несколько файлов SVG с помощью Inkscape, внедрил туда растровые изображения, а затем удалил исходные растровые изображения.
Теперь я хотел бы извлечь растровое изображение из SVG, чтобы вернуть исходные растровые изображения. Я могу открыть SVG в Inkscape, но копирование растрового изображения копирует его в искаженном виде, если растровое изображение не было масштабировано с сохранением соотношения сторон. Кроме того, он копирует растровое изображение целевого размера, который может быть больше или меньше исходного растрового изображения.
ИМХО, растровое изображение в SVG доступно в исходном разрешении вместе с внесенными в него изменениями (размер, поворот и т. д.).
Поэтому я ищу инструмент, который
Я не ищу самодельное решение для программирования. Я знаю, что SVG — это XML, а данные содержатся в <image>
тегах в кодировке base64. Я, вероятно, сделаю это, если другие решения (протестированные и т. д.) недоступны.
Я долго не получал ответа, поэтому, наконец, я реализовал его на C#. Вы можете использовать бесплатную версию Microsoft Visual Studio 2017 Community Edition .
Он соответствует требованиям:
Создайте консольное приложение и создайте 3 файла с указанным ниже содержимым.
Файл 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);
}
}
}
}
}
Файл 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);
}
}
}
Файл 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;
}
}
}