VXdat文件解码到图片的代码很多了,但是没有看到从数据信息cha询图片位置的代码。
众所周知,VX图片(或者其他文件)的都是先上传到TX的CDN服务器,然后服务器返回给你一个fileId从服务器下载,我们收到的图片信息往往是这样的:
[XML] 纯文本查看 复制代码
{
"from_wxid": "***",
"msgid": "6473877768939539653",
"raw_msg": "
<?xml version=\"1.0\"?>
<msg>
<img aeskey=\"1076d11a1875a8a78fd2e6eb7c194688\" encryver=\"1\" cdnthumbaeskey=\"1076d11a1875a8a78fd2e6eb7c194688\" cdnthumburl=\"3057020100044b30490201000204c1473b4002032df7fa02040eecd476020468906599042464353132353132662d623636662d346139652d613232642d6439393632623635613535360204052418020201000405004c4dfe00\" cdnthumblength=\"7785\" cdnthumbheight=\"240\" cdnthumbwidth=\"135\" cdnmidheight=\"0\" cdnmidwidth=\"0\" cdnhdheight=\"0\" cdnhdwidth=\"0\" cdnmidimgurl=\"3057020100044b30490201000204c1473b4002032df7fa02040eecd476020468906599042464353132353132662d623636662d346139652d613232642d6439393632623635613535360204052418020201000405004c4dfe00\" length=\"750297\" md5=\"d898add08467de961353a319a3210ffa\">
<secHashInfoBase64 />
<live>
<duration>0</duration>
<size>0</size>
<md5 />
<fileid />
<hdsize>0</hdsize>
<hdmd5 />
<hdfileid />
<stillimagetimems>0</stillimagetimems>
</live>
</img>
<platform_signature />
<imgdatahash />
<ImgSourceInfo>
<ImgSourceUrl />
<BizType>0</BizType>
</ImgSourceInfo>
</msg>",
"room_wxid": "***",
"timestamp": 1754293889,
"to_wxid": "***",
"wx_type": 3
}
一大堆数据无从下手,其实cdnthumbaeskey和cdnthumburl就是用来从CDN服务器请求图片信息的。这里讨论的是用消息ID从数据库cha询路径的地址:
大致步骤:
先用$"select * from MSG where MsgSvrID= {MsgId}"查到bytesExtra文本,再Base64解码文本。(3.x版本用的是MSG表,4.0好像已经改成Message表了。)
[C#] 纯文本查看 复制代码
string jsonString = await API.ExecSql(dbHandle0, $"select * from MSG where MsgSvrID= {MsgId}");
JObject jsonObject = JObject.Parse(jsonString);
byte[] bytesExtra = Array.Empty<byte>();
try
{
if (jsonObject["data"] != null && jsonObject["data"].HasValues && jsonObject["data"][0] != null)
{
ocrContext.Finished = true;
string bytesExtraBase64 = jsonObject["data"][0]["BytesExtra"]?.ToString();
if (!string.IsNullOrEmpty(bytesExtraBase64))
{
bytesExtra = Convert.FromBase64String(bytesExtraBase64);
}
}
}
catch (Exception e)
{
Debug.Print(e.Message);
}
解码后都得的Proto数组里面就包含图片路径:
[C#] 纯文本查看 复制代码
#region 消息结构
[ProtoContract]
public class GetDatPath
{
[ProtoMember(1, IsRequired = true)]
public byte[] field1;
[ProtoMember(2, IsRequired = false)]
public int field2;
[ProtoMember(3, IsRequired = true)]
public DatPathInfo dataPath;
}
[ProtoContract]
public class DatPathInfo
{
[ProtoMember(1, IsRequired = true)]
public int item1;
[ProtoMember(2, IsRequired = true)]
public List<string> list;
}
#endregion
public static string GetDatFilePath(byte[] bytesIn)//bytesExtra解码后的数组
{
try
{
using (MemoryStream ms = new MemoryStream(bytesIn))
{
var result = Serializer.Deserialize<GetDatPath>(ms);
if (!string.IsNullOrEmpty(result.dataPath.list[result.dataPath.list.Count - 1]))
{
return result.dataPath.list[result.dataPath.list.Count - 2];
}
}
}
catch (Exception ex)
{
Debug.Print($"解析错误: {ex.Message}");
}
return null;
}