Для справки я наткнулся на этот вопрос и использовал ответ Джоэла Мюллера, но решил автоматизировать синтаксический анализ путей изображения. Может быть, кто-то найдет мой код полезным для стартера аналогичного решения - он довольно грубый и грязный, но, похоже, хорошо справляется с этой задачей.
Я использую ресурсы C#, внутри своих html-файлов я помещаю только имена файлов изображений. Он также позволяет мне открыть файл в обычном браузере для тестирования того, как он будет выглядеть. Код автоматически ищет ресурс с тем же именем, что и имя файла внутри html, сохраняет его в каталоге данных приложения и заменяет путь.
Следует также отметить, что приложение будет перезаписывать файл, если он отличается от уже сохраненного. В основном это было необходимо для разработки, но на самом деле у меня не было много таких файлов, поэтому здесь меня не волновало потеря производительности. Опуская эту проверку и предполагая, что файлы обновлены, необходимо повысить производительность.
Settings.Default.ApplicationId
- простая строка с именем приложения, используемым для имени каталога внутри данных приложения.
Вот как мой класс в конечном итоге ищет:
class MyHtmlImageEmbedder
{
static protected string _appDataDirectory =
Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
Settings.Default.ApplicationId);
static public string getHtml()
{
String apiHelp = Resources.html_file;
Regex regex = new Regex(@"src=\""(.*)\""", RegexOptions.IgnoreCase);
MatchCollection mc = regex.Matches(apiHelp);
foreach (Match m in mc)
{
string filename = m.Groups[1].Value;
Image image = Resources.ResourceManager.GetObject(Path.GetFileNameWithoutExtension(filename)) as Image;
if (image != null)
{
var path = getPathTo(Path.GetFileNameWithoutExtension(filename) + ".png", imageToPngByteArray(image));
apiHelp = apiHelp.Replace(filename, path);
}
}
return apiHelp;
}
static public string getPathTo(string filename, byte[] contentBytes)
{
Directory.CreateDirectory(_appDataDirectory);
var path = Path.Combine(_appDataDirectory, filename);
if (!File.Exists(path) || !byteArrayCompare(contentBytes, File.ReadAllBytes(path)))
{
File.WriteAllBytes(path, contentBytes);
}
return path;
}
[DllImport("msvcrt.dll", CallingConvention = CallingConvention.Cdecl)]
static extern int memcmp(byte[] b1, byte[] b2, long count);
public static bool byteArrayCompare(byte[] b1, byte[] b2)
{
// Validate buffers are the same length.
// This also ensures that the count does not exceed the length of either buffer.
return b1.Length == b2.Length && memcmp(b1, b2, b1.Length) == 0;
}
public static byte[] imageToPngByteArray(Image image)
{
MemoryStream ms = new MemoryStream();
image.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
return ms.ToArray();
}
}
Пожалуйста, обратите внимание, что byteArrayCompareFunction использует memcmp только из соображений производительности, но она может быть легко замещена простым сравнением петли.
Тогда я просто звоню browser.NavigateToString(MyHtmlImageEmbedder.getHtml());
.
Мое приложение генерирует HTML, оно не существует на URL-адресе. – Tony 2010-12-08 19:00:07
Но, как и любая другая HTML-страница в мире, любые изображения или CSS должны быть указаны по URL-адресу. Нет такой вещи, как HTML-страница со встроенными изображениями. – 2010-12-08 19:01:39
Да, наверное. Вы все это продумали? Может быть, пришло время остановиться и прочитать учебник по HTML? – 2010-12-08 19:08:37