Blink 档案中的图像编码

问题描述 投票:0回答:2

我有一个从 Chrome 浏览器保存的 Blink 存档(mht 格式)。 我正在尝试转换该部分

Content-Type: image/jpeg
Content-Transfer-Encoding: binary
Content-Location: https://some_url

ÿØÿà^@^PJFIF^@^A^A^A^@`^@`^@^@ÿÛ^@C^@^A^A^A^A^A^A^A^A^A^A^A^A^A^A^A^A^A^A^A^A^A^A^A^A^A^A^A^A^A^A^A^A^A^A^A^A^A^A^A^A^A^A^A^A^A^A^A^A^A^A^A^A^A^A^A^A^A^A^A^A^A^A^A^AÿÛ^
^KÿÄ^@µ^P^@^B^A^C^C^B^D^C^E^E^D^D^@^@^A}^A^B^C^@

图像文件如下

string s = "\nÿØÿà^@^PJ..."
byte [] result = System.Convert.FromBase64String(s)
File.WriteAllBytes("image.jpg", result);

我有一条错误消息

The input is not a valid Base-64 string as it contains a non-base 64 character, more than two padding characters, or an illegal character among the padding characters.

我该如何修复它?字符串中可能有

\n
个字符。当我用空字符串替换
\n
时,它没有帮助。

c# base64 mime blink mhtml
2个回答
1
投票

因为您提到您想用 Java 实现您的解决方案,所以我开发了一个可以轻松转换为 Java 的简单解决方案。

以下代码读取

robot.mhtml
文件并将每个部分的内容转储到
out/
目录中的单独文件中:

using System.Text;
using System.Text.RegularExpressions;

Encoding encoding = Encoding.GetEncoding("ISO-8859-1");

string mhtml = File.ReadAllText("./robot.mhtml", encoding);

MatchCollection matches = Regex.Matches(
    mhtml,
    @"Content-Location: .*/(?<name>.*)\n\r\n(?<content>(\n|.)+?)(?=\n------MultipartBoundary--)"
);

Directory.CreateDirectory("out");

foreach (Match match in matches)
{
    File.WriteAllText("out/" + match.Groups["name"].Value, match.Groups["content"].Value, encoding);
}

我测试了它,它有效:

让我为您提供正则表达式的完整解释:

  • 正则表达式尝试提取每个部分名称(使用
    Content-Location
    标头的最后部分)及其内容。
  • 没有单行标志
    .
    包括除
    \n
    之外的所有内容。因此,当我们打算包含所有内容(包括新行)时,我们应该使用
    (.|\n)
  • 遵循 HTTP 协议,标头和内容之间有一个附加的
    \r\n
  • (?<group_name>pattern)
    创建一个名为
    group_name
    和指定的
    pattern
    的正则表达式组,允许我们请求匹配仅返回完整匹配中的这些特定部分。
  • +?
    表示不应贪婪地扩展文本。如果您使用简单的
    +
    ,它会捕获内容直到最后一个
    \n------MultipartBoundary--
    (导致仅提取一个文件)。但是,我们的目标是捕获内容,直到第一次出现为止。
  • .+(?=sequence)
    表示搜索直至找到
    sequence
    (有关更多信息,请参阅此处)。

其他一些注意事项:

  • HTTP 消息使用
    ISO-8859-1
    进行编码。因此,您应该使用这种编码来读取和写入文件。
  • This是我测试解决方案的文件。我访问了您提到的网站并使用 Android 上的 Chrome 下载了该页面。

除了编码和日志记录之外,您还可以在这个特定于 dotnet 的正则表达式测试器中测试自定义的正则表达式以观察结果和捕获的组:


1
投票

从您共享的代码片段来看,您拥有的数据似乎不是 Base64 编码的,而是直接表示 JPEG 文件的字节(从开头的幻数 ÿØÿà 可以看出,它对应于 JPEG)。

如果是这种情况,则根本不需要进行Base64转换,需要直接将此字符串转换为字节。

在C#中,您可以使用Encoding类将字符串转换为字节。如果字符串表示字节为 UTF-8,您可以像这样转换它:

string s = "\nÿØÿà^@^PJ...";
byte[] result = Encoding.UTF8.GetBytes(s);
File.WriteAllBytes("image.jpg", result);
© www.soinside.com 2019 - 2024. All rights reserved.