作为参考,我偶然发现了这个问题并使用了 Joel Mueller 的答案,但决定自动解析图像路径。也许有人会发现我的代码对于启动类似解决方案很有用 - 它非常粗糙和肮脏,但似乎做得很好。
我正在使用 C# 资源,在我的 html 文件中,我只放置图像文件名。它还允许我在普通浏览器中打开文件以测试它的外观。代码自动在html中查找与filename同名的资源,保存在应用数据目录下,并替换路径。
还值得注意的是,如果文件与已保存的文件不同,应用程序将覆盖该文件。主要是开发需要,但是我真的没有很多这些文件,所以我不在乎这里的性能损失。省略此检查并假设文件是最新的应该会提高性能。
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());。