在网络开发中,为了提升网页的加载速度,有时会将图像直接以Base64编码的形式嵌入HTML文件中。这种方式可以减少HTTP请求的数量,并且允许网页作为一个单一文件保存。然而,这种方法在某些浏览器,尤其是Internet Explorer 8及以下版本中存在兼容性问题。本文将介绍一种简单的方法,用于提取这些内嵌图像,并将HTML转换为使用外部图像。
通常情况下,图像是通过以下语法包含在HTML中的img src="Image1.png"。然而,Data URI语法允许图像直接嵌入,从而减少了HTTP请求的数量。
大多数编辑器并不使用Data URI语法。但是,从SeaMonkey 2.1 Composer(MozillaHTML编辑器)开始,通过拖放导入的图像会使用这种语法。认为这是一个相当糟糕的改变,尤其是因为它不明显,并且与2.0版本的行为发生了变化。在情况下,在发现它没有链接图像而是嵌入它们之前,已经制作了一个包含50多张图像的大型HTML文件。
令人惊讶的是,有很多在线工具可以将图像转换为Data URI格式,但没有找到能够反向操作的工具。因为不希望手动编辑文档,所以编写了一个快速实用工具,将图像提取到磁盘上,并更改HTML以使用外部图像。这允许文档被包括Internet Explorer 8在内的任何标准浏览器加载。
源代码非常针对特定需求,有很多限制。然而,已经发布了它,以便作为基础,供在有相同需求时扩展。
ImageExtract是一个控制台应用程序,接受一个参数。参数是输入的HTML文件。图像将输出到同一目录中,新的HTML文件将有一个"-new"后缀。因此,如果输入是index.html,输出的HTML将是index-new.html。
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
namespace ImageExtract {
class Program {
static void Main(string[] aArgs) {
string xSrcPathname = aArgs[0];
string xPath = Path.GetDirectoryName(xSrcPathname);
string xDestPathname = Path.Combine(xPath, Path.GetFileNameWithoutExtension(xSrcPathname) + "-New.html");
int xImgIdx = 0;
Console.WriteLine("Processing " + Path.GetFileName(xSrcPathname));
string xSrc = File.ReadAllText(xSrcPathname);
var xDest = new StringBuilder();
string xStart = @"data:image/png;base64,";
string xB64;
int x = 0;
int y = 0;
int z = 0;
do {
x = xSrc.IndexOf(xStart, z);
if (x == -1) {
break;
}
xDest.Append(xSrc.Substring(z, x - z));
y = xSrc.IndexOf(""", x + 1);
xB64 = xSrc.Substring(x + xStart.Length, y - x - xStart.Length);
byte[] xImgData = System.Convert.FromBase64String(xB64);
string xImgName;
do {
xImgIdx++;
xImgName = "Image" + xImgIdx.ToString("0000") + ".png";
} while (File.Exists(Path.Combine(xPath, xImgName)));
Console.WriteLine("Extracting " + xImgName);
xDest.Append(xImgName);
File.WriteAllBytes(Path.Combine(xPath, xImgName), xImgData);
z = y;
} while (true);
xDest.Append(xSrc.Substring(z));
File.WriteAllText(xDestPathname, xDest.ToString());
Console.WriteLine("Output to " + Path.GetFileName(xDestPathname));
}
}
}