c# - 有没有办法从所有类型的文件中提取所有元数据?
问题描述
我正在尝试从一堆文件中提取元数据。这些文件可以是图像、视频或任何类型的文件。无论类型如何,我都想从文件中提取所有可用的元数据。我尝试使用WindowsAPICodePack
and Shell32
。我能够提取一堆属性,但我需要文件中提供的“投影类型”元数据。但两者WindowsAPICodePack
并Shell32
未能提取相同。有什么解决办法吗?
这是Shell 32
我尝试过的代码
List<string> arrHeaders = new List<string>();
List<Tuple<int, string, string>> attributes = new List<Tuple<int, string, string>>();
Shell32.Shell shell = new Shell32.Shell();
var strFileName = @"C:\Users\Admin\Google Drive\image.jpg";
Shell32.Folder objFolder = shell.NameSpace(System.IO.Path.GetDirectoryName(strFileName));
Shell32.FolderItem folderItem = objFolder.ParseName(System.IO.Path.GetFileName(strFileName));
for (int i = 0; i < short.MaxValue; i++)
{
string header = objFolder.GetDetailsOf(null, i);
if (String.IsNullOrEmpty(header))
break;
arrHeaders.Add(header);
}
// The attributes list below will contain a tuple with attribute index, name and value
// Once you know the index of the attribute you want to get,
// you can get it directly without looping, like this:
var Authors = objFolder.GetDetailsOf(folderItem, 20);
for (int i = 0; i < arrHeaders.Count; i++)
{
var attrName = arrHeaders[i];
var attrValue = objFolder.GetDetailsOf(folderItem, i);
var attrIdx = i;
attributes.Add(new Tuple<int, string, string>(attrIdx, attrName, attrValue));
Debug.WriteLine("{0}\t{1}: {2}", i, attrName, attrValue);
}
Console.ReadLine();
下面给出了代码WindowsAPICodePack
。
ShellObject file = ShellObject.FromParsingName(path);
var props = file.Properties.DefaultPropertyCollection;
var camera = file.Properties.GetProperty(SystemProperties.System.Photo.CameraModel);
解决方案
好的,经过一番搜索,我最终使用了Phil Harvey 的 ExifTool。
该工具在提取大量元数据方面非常有效,尤其是我特别需要的 - 'ProjectionType'。此属性用于检查上传的文件是否为 360 视频/图像。这几乎就是我最终的结果。
public List<Metadata> ExtractMetaDataExifTool(string filepath, string ExifToolPath)
{
#region ReadFromFile
string output = "";
var lstMetadata = new List<Metadata>();
using (var p = new Process())
{
// exiftool command
string toolPath = "";
toolPath += " -s ";
toolPath += "-fast -G -t -m -q -q -n ";
toolPath += "\"" + filepath + "\"";
System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
startInfo.FileName = "\"" + ExifToolPath + "\\exiftool.exe" + "\"";
startInfo.Arguments = toolPath;
startInfo.RedirectStandardOutput = true;
startInfo.UseShellExecute = false;
p.StartInfo = startInfo;
bool status = p.Start();
StringBuilder q = new StringBuilder();
while (!p.HasExited)
{
q.Append(p.StandardOutput.ReadToEnd());
}
output = q.ToString();
p.WaitForExit();
}
#endregion ReadFromFile
#region ExtractFileMetadataFromString
while (output.Length > 0)
{
int epos = output.IndexOf('\r');
if (epos < 0)
epos = output.Length;
string tmp = output.Substring(0, epos);
int tpos1 = tmp.IndexOf('\t');
int tpos2 = tmp.IndexOf('\t', tpos1 + 1);
if (tpos1 > 0 && tpos2 > 0)
{
string taggroup = tmp.Substring(0, tpos1);
++tpos1;
string tagname = tmp.Substring(tpos1, tpos2 - tpos1);
++tpos2;
string tagvalue = tmp.Substring(tpos2, tmp.Length - tpos2);
// special processing for tags with binary data
tpos1 = tagvalue.IndexOf(", use -b option to extract");
if (tpos1 >= 0)
tagvalue.Remove(tpos1, 26);
if (!string.IsNullOrEmpty(taggroup) && !string.IsNullOrEmpty(tagname) && !string.IsNullOrEmpty(tagvalue))
{
lstMetadata.Add(new Metadata
{
group = taggroup?.Trim(),
name = tagname?.Trim(),
value = tagvalue?.Trim()
});
}
}
// is \r followed by \n ?
if (epos < output.Length)
epos += (output[epos + 1] == '\n') ? 2 : 1;
output = output.Substring(epos, output.Length - epos);
}
#endregion ExtractFileMetadataFromString
return lstMetadata;
}
推荐阅读
- node.js - Mongoose 只开启部分收藏
- pine-script - 如何克服“绘图”和“填充”功能限制
- javascript - Javascript从多个数组中查找所有重复项
- javascript - 阻止代码从 JS 中的检查元素运行?
- ffmpeg - 使用 ffmpeg 调整高清视频大小并将其裁剪为方形视频
- javascript - guild.channels.cache.array() 返回一个空数组。与 client.channels.cache.array() 相同
- prometheus - 如何使用普罗米修斯中的标签从同一个计数器中获取百分比?
- flutter - Flutter Dart 从对象列表中获取字符串列表
- python - 如何在Python中索引每行超过一个单词的输入单词
- tensorflow - 在本地 pc 上从源代码构建 tensorflow 并在远程 pc 上部署