|
|
using System.Drawing;
|
|
|
using System.Drawing.Imaging;
|
|
|
using Infrastructure.CloudSdk.minio;
|
|
|
using Infrastructure.CloudSdk.wayline;
|
|
|
using Infrastructure.Extensions;
|
|
|
using Infrastructure.Utilities;
|
|
|
using MetadataExtractor;
|
|
|
using MetadataExtractor.Formats.Exif;
|
|
|
using Newtonsoft.Json;
|
|
|
using Newtonsoft.Json.Linq;
|
|
|
using NUnit.Framework;
|
|
|
using OpenAuth.Repository.Domain;
|
|
|
|
|
|
namespace OpenAuth.WebApi.boot;
|
|
|
|
|
|
public class TestAbc
|
|
|
{
|
|
|
//[Test]
|
|
|
public void TestDser()
|
|
|
{
|
|
|
var json =
|
|
|
@" {""bid"":""67fea48d-d350-45c4-babb-df5256907172"",""data"":{""result"":0},""method"":""flighttask_prepare"",""tid"":""dc89588c-0f68-4d5e-91e2-a5d678efd429"",""timestamp"":1750406045000}
|
|
|
";
|
|
|
var result = JsonConvert.DeserializeObject<TopicServicesRequest<dynamic>>(json);
|
|
|
long code = result.data.result;
|
|
|
Console.WriteLine(code);
|
|
|
}
|
|
|
|
|
|
//[Test]
|
|
|
public void TestGetSuffix()
|
|
|
{
|
|
|
var fileName = "test.jpg";
|
|
|
var suffix = Path.GetExtension(fileName);
|
|
|
Console.WriteLine(suffix);
|
|
|
}
|
|
|
|
|
|
//[Test]
|
|
|
public async Task TestTempLink()
|
|
|
{
|
|
|
MinioService minioService = new MinioService();
|
|
|
// 76382c23-8c63-44b7-acb7-c9b69e85b526/3893eb7c-7f24-4ae0-8291-01c13a39ebc6/DJI_202506301510_002_3893eb7c-7f24-4ae0-8291-01c13a39ebc6/
|
|
|
string url = await minioService.GetObjectUrl("test",
|
|
|
"76382c23-8c63-44b7-acb7-c9b69e85b526/3893eb7c-7f24-4ae0-8291-01c13a39ebc6/DJI_202506301510_002_3893eb7c-7f24-4ae0-8291-01c13a39ebc6/DJI_20250630151113_0001_V.jpeg");
|
|
|
Console.Write(url);
|
|
|
}
|
|
|
|
|
|
//[Test]
|
|
|
public void TestSubstring()
|
|
|
{
|
|
|
var str1 = "2025-07-04"; //
|
|
|
var str2 = "dev/2025-07-04/abc/";
|
|
|
var index = str2.IndexOf(str1) + str1.Length;
|
|
|
Console.WriteLine(index);
|
|
|
Console.WriteLine(str2.Substring(index));
|
|
|
}
|
|
|
|
|
|
//[Test]
|
|
|
public void TestJson()
|
|
|
{
|
|
|
var json =
|
|
|
"{\n \"bid\": \"1d988af7-aa93-4141-9d9b-b29e437f2338\",\n \"data\": {\n \"file\": {\n \"cloud_to_cloud_id\": \"DEFAULT\",\n \"ext\": {\n \"drone_model_key\": \"0-100-1\",\n \"flight_id\": \"9ab67dc0-6e6f-4c58-a178-bef76f7e0b15\",\n \"is_original\": true,\n \"media_index\": 525705,\n \"payload_model_key\": \"1-99-0\"\n },\n \"metadata\": {\n \"absolute_altitude\": 157.967,\n \"created_time\": \"2025-07-11T11:15:02+08:00\",\n \"gimbal_yaw_degree\": -44.7,\n \"relative_altitude\": 76.584,\n \"shoot_position\": {\n \"lat\": 35.13427,\n \"lng\": 118.29459541666667\n }\n },\n \"name\": \"DJI_20250711111502_0088_V.jpeg\",\n \"object_key\": \"6196fb6b-3753-4885-a085-1b91713349f3/9ab67dc0-6e6f-4c58-a178-bef76f7e0b15/DJI_202507111111_002_9ab67dc0-6e6f-4c58-a178-bef76f7e0b15/DJI_20250711111502_0088_V.jpeg\",\n \"path\": \"\"\n },\n \"flight_task\": {\n \"expected_file_count\": 91,\n \"flight_type\": 0,\n \"uploaded_file_count\": 91\n },\n \"progress\": 0,\n \"result\": 0\n },\n \"method\": \"file_upload_callback\",\n \"need_reply\": 1,\n \"tid\": \"80803634-94c5-4cac-92fe-8a36e09c9a00\",\n \"timestamp\": 1752203903285,\n \"gateway\": \"8UUXN5400A079H\"\n}";
|
|
|
var result = JsonConvert.DeserializeObject<TopicServicesRequest<dynamic>>(json);
|
|
|
var data = result.data;
|
|
|
Console.WriteLine(data.flight_task.flight_type);
|
|
|
Console.WriteLine(data.file.ext.drone_model_key);
|
|
|
Console.WriteLine(data.file.ext.flight_id);
|
|
|
Console.WriteLine(data.file.ext.media_index);
|
|
|
Console.WriteLine(data.file.ext.payload_model_key);
|
|
|
Console.WriteLine(data.file.metadata.absolute_altitude);
|
|
|
Console.WriteLine(data.file.metadata.created_time);
|
|
|
Console.WriteLine(data.file.metadata.gimbal_yaw_degree);
|
|
|
Console.WriteLine(data.file.metadata.relative_altitude);
|
|
|
Console.WriteLine(data.file.metadata.shoot_position.lat);
|
|
|
Console.WriteLine(data.file.metadata.shoot_position.lng);
|
|
|
Console.WriteLine(data.file.name);
|
|
|
Console.WriteLine(data.file.object_key);
|
|
|
Console.WriteLine(data.file.path);
|
|
|
if (result.need_reply.Equals(1))
|
|
|
{
|
|
|
Console.WriteLine("需要回复");
|
|
|
}
|
|
|
|
|
|
Console.WriteLine(result.need_reply);
|
|
|
string createdTime = data.file.metadata.created_time;
|
|
|
Console.WriteLine(createdTime.ToDateTime());
|
|
|
}
|
|
|
|
|
|
//[Test]
|
|
|
public void TestCombi()
|
|
|
{
|
|
|
string tempPath = Path.GetTempPath();
|
|
|
Console.WriteLine(tempPath);
|
|
|
}
|
|
|
|
|
|
// [Test]
|
|
|
public void TestTimeZone()
|
|
|
{
|
|
|
long[] times =
|
|
|
{
|
|
|
1753146586552,
|
|
|
1753146587621,
|
|
|
1753146587744,
|
|
|
1753146588532,
|
|
|
1753146588822,
|
|
|
1753146588959,
|
|
|
1753146590022,
|
|
|
1753146590155,
|
|
|
1753146590533,
|
|
|
1753146591251,
|
|
|
1753146591376,
|
|
|
1753146592452,
|
|
|
1753146592582,
|
|
|
1753146593668,
|
|
|
1753146593792,
|
|
|
};
|
|
|
var y = times[0];
|
|
|
foreach (var time in times)
|
|
|
{
|
|
|
var x = DateTimeOffset.FromUnixTimeMilliseconds(time);
|
|
|
Console.WriteLine(x.ToLocalTime().ToString("yyyy-MM-dd HH:mm:ss:fff") + $" {time - y}");
|
|
|
y = time;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
//[Test]
|
|
|
public void Test()
|
|
|
{
|
|
|
var content =
|
|
|
"{\"cityid\":\"101120911\",\"date\":\"2025-08-01\",\"week\":\"星期五\",\"update_time\":\"10:18\",\"city\":\"兰山\",\"cityEn\":\"lanshan\",\"country\":\"中国\",\"countryEn\":\"China\",\"wea\":\"多云\",\"wea_img\":\"yun\",\"tem\":\"27.8\",\"tem1\":\"30\",\"tem2\":\"26\",\"win\":\"东北风\",\"win_speed\":\"3级\",\"win_meter\":\"12km/h\",\"humidity\":\"87%\",\"visibility\":\"16km\",\"pressure\":\"987\",\"air\":\"27\",\"air_pm25\":\"17\",\"air_level\":\"优\",\"air_tips\":\"各类人群可多参加户外活动,多呼吸一下清新的空气。\",\"alarm\":{\"alarm_type\":\"暴雨\",\"alarm_level\":\"蓝色\",\"alarm_title\":\"山东省发布暴雨蓝色预警\",\"alarm_content\":\"山东省气象台于8月1日06时00分继续发布暴雨蓝色预警:预计1日白天到夜间,临沂和枣庄有小到中雨局部暴雨并伴有雷电,日照、青岛、威海和烟台有雷雨或阵雨局部大雨或暴雨,鲁西北地区天气多云,其他地区局部有雷雨或阵雨,雷雨地区雷雨时阵风7\uff5e9级。(预警信息来源:国家预警信息发布中心)\"},\"rain_pcpn\":\"3.8\",\"uvIndex\":\"2\",\"uvDescription\":\"低\",\"wea_day\":\"中雨\",\"wea_day_img\":\"yu\",\"wea_night\":\"小雨\",\"wea_night_img\":\"yu\",\"sunrise\":\"05:15\",\"sunset\":\"19:10\",\"aqi\":{\"update_time\":\"08:05\",\"air\":\"27\",\"air_level\":\"优\",\"air_tips\":\"各类人群可多参加户外活动,多呼吸一下清新的空气。\",\"pm25\":\"17\",\"pm25_desc\":\"优\",\"pm10\":\"27\",\"pm10_desc\":\"优\",\"o3\":\"21\",\"o3_desc\":\"\",\"no2\":\"14\",\"no2_desc\":\"\",\"so2\":\"9\",\"so2_desc\":\"\",\"co\":\"0.4\",\"co_desc\":\"\",\"kouzhao\":\"不用佩戴口罩\",\"yundong\":\"适宜运动\",\"waichu\":\"适宜外出\",\"kaichuang\":\"适宜开窗\",\"jinghuaqi\":\"不需要打开\"},\"nums\":14}";
|
|
|
var weather = JsonConvert.DeserializeObject<JObject>(content);
|
|
|
var win_meter = weather.GetValue("win_mete")?.Value<string>(); // 风速
|
|
|
Console.WriteLine(win_meter);
|
|
|
}
|
|
|
|
|
|
static void ReadExifData(string filePath)
|
|
|
{
|
|
|
if (!File.Exists(filePath))
|
|
|
{
|
|
|
Console.WriteLine("文件不存在!");
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
try
|
|
|
{
|
|
|
// 读取所有元数据目录
|
|
|
var directories = ImageMetadataReader.ReadMetadata(filePath);
|
|
|
|
|
|
Console.WriteLine("所有元数据目录:");
|
|
|
foreach (var dir in directories)
|
|
|
{
|
|
|
Console.WriteLine($"- {dir.GetType().Name}");
|
|
|
}
|
|
|
|
|
|
// 更通用的方式获取所有EXIF相关标签
|
|
|
Console.WriteLine("\nEXIF 数据:");
|
|
|
Console.WriteLine("====================");
|
|
|
|
|
|
// 查找所有包含EXIF标签的目录
|
|
|
foreach (var directory in directories)
|
|
|
{
|
|
|
// 检查目录是否包含EXIF标签
|
|
|
if (directory is ExifDirectoryBase)
|
|
|
{
|
|
|
foreach (var tag in directory.Tags)
|
|
|
{
|
|
|
Console.WriteLine($"{tag.Name}: {tag.Description}");
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
Console.WriteLine($"错误: {ex.Message}");
|
|
|
Console.WriteLine($"堆栈跟踪: {ex.StackTrace}");
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 获取属性名称
|
|
|
static string GetPropertyName(int id)
|
|
|
{
|
|
|
// 常见的EXIF属性ID映射
|
|
|
var propertyNames = new System.Collections.Generic.Dictionary<int, string>
|
|
|
{
|
|
|
{ 0x010F, "制造商" },
|
|
|
{ 0x0110, "相机型号" },
|
|
|
{ 0x0132, "日期时间" },
|
|
|
{ 0x829A, "曝光时间" },
|
|
|
{ 0x829D, "光圈值" },
|
|
|
{ 0x8822, "自动曝光、光圈优先、快门优先、M 档等" },
|
|
|
{ 0x8827, "ISO速度" },
|
|
|
{ 0x9003, "拍摄日期" },
|
|
|
{ 0x9204, "曝光程序" },
|
|
|
{ 0x9207, "测光模式" },
|
|
|
{ 0x9209, "闪光灯" },
|
|
|
{ 0x920A, "物理焦距" },
|
|
|
{ 0xA000, "EXIF版本" },
|
|
|
{ 0xA001, "镜头型号" },
|
|
|
{ 0x010E, "主题" },
|
|
|
{ 0x0131, "程序名称" },
|
|
|
{ 0x0112, "镜头方向" },
|
|
|
{ 0x9202, "最大光圈" },
|
|
|
};
|
|
|
|
|
|
return propertyNames.TryGetValue(id, out string name) ? name : $"属性 ID: 0x{id:X4}";
|
|
|
}
|
|
|
|
|
|
// 获取属性值
|
|
|
static string GetPropertyValue(PropertyItem prop)
|
|
|
{
|
|
|
// 根据属性类型解析值
|
|
|
switch (prop.Type)
|
|
|
{
|
|
|
case 1: // 字节型
|
|
|
return BitConverter.ToString(prop.Value);
|
|
|
case 2: // 字符串
|
|
|
return System.Text.Encoding.ASCII.GetString(prop.Value).Trim('\0');
|
|
|
case 3: // 16位整数
|
|
|
return BitConverter.ToInt16(prop.Value, 0).ToString();
|
|
|
case 4: // 32位整数
|
|
|
return BitConverter.ToInt32(prop.Value, 0).ToString();
|
|
|
case 5: // rational (两个32位整数的比值)
|
|
|
int numerator = BitConverter.ToInt32(prop.Value, 0);
|
|
|
int denominator = BitConverter.ToInt32(prop.Value, 4);
|
|
|
if (denominator != 0)
|
|
|
return ((double)numerator / denominator).ToString("0.00");
|
|
|
return numerator.ToString();
|
|
|
case 10: // signed rational
|
|
|
int num = BitConverter.ToInt32(prop.Value, 0);
|
|
|
int den = BitConverter.ToInt32(prop.Value, 4);
|
|
|
if (den != 0)
|
|
|
return ((double)num / den).ToString("0.00");
|
|
|
return num.ToString();
|
|
|
default:
|
|
|
return $"({prop.Type}) {BitConverter.ToString(prop.Value)}";
|
|
|
}
|
|
|
}
|
|
|
|
|
|
//[Test]
|
|
|
public void TestGetExif()
|
|
|
{
|
|
|
ReadExifData("f:/DJI_20250805014002_0001_V.jpeg");
|
|
|
}
|
|
|
|
|
|
//[Test]
|
|
|
public void TestMem()
|
|
|
{
|
|
|
var client = new MinioService();
|
|
|
var y = client.GetObjectAsStream("test",
|
|
|
"f9443fba-5ba9-4d9e-aea0-5238bdb73f72/15a21693-3d05-4923-b46d-90fc18ef312e/DJI_202508050138_002_15a21693-3d05-4923-b46d-90fc18ef312e/DJI_20250805014002_0001_V.jpeg");
|
|
|
var directories = ImageMetadataReader.ReadMetadata(y.Result);
|
|
|
// 查找所有包含EXIF标签的目录
|
|
|
foreach (var directory in directories)
|
|
|
{
|
|
|
// 检查目录是否包含EXIF标签
|
|
|
if (directory is ExifDirectoryBase)
|
|
|
{
|
|
|
foreach (var tag in directory.Tags)
|
|
|
{
|
|
|
Console.WriteLine($"{tag.Name}: {tag.Description} {tag.DirectoryName}");
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// [Test]
|
|
|
public void TestPi()
|
|
|
{
|
|
|
var client = new MinioService();
|
|
|
var y = client.GetObjectAsStream("test",
|
|
|
"f9443fba-5ba9-4d9e-aea0-5238bdb73f72/15a21693-3d05-4923-b46d-90fc18ef312e/DJI_202508050138_002_15a21693-3d05-4923-b46d-90fc18ef312e/DJI_20250805014002_0001_V.jpeg");
|
|
|
using (Image image = Image.FromStream(y.Result))
|
|
|
{
|
|
|
Console.WriteLine("图片基本信息:");
|
|
|
Console.WriteLine($"尺寸: {image.Width} x {image.Height}");
|
|
|
Console.WriteLine($"格式: {image.RawFormat.Guid}");
|
|
|
Console.WriteLine();
|
|
|
|
|
|
Console.WriteLine("图片详细属性:");
|
|
|
int x = 0;
|
|
|
// 遍历所有属性
|
|
|
foreach (PropertyItem prop in image.PropertyItems)
|
|
|
{
|
|
|
x = x + prop.Len;
|
|
|
try
|
|
|
{
|
|
|
string value = GetPropertyValue(prop);
|
|
|
Console.WriteLine($"{GetPropertyName(prop.Id)}: {value}");
|
|
|
}
|
|
|
catch
|
|
|
{
|
|
|
// 有些属性可能无法解析,直接跳过
|
|
|
continue;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// [Test]
|
|
|
public void TestGetEx()
|
|
|
{
|
|
|
var client = new MinioService();
|
|
|
var y = client.GetObjectAsStream("test",
|
|
|
"f9443fba-5ba9-4d9e-aea0-5238bdb73f72/15a21693-3d05-4923-b46d-90fc18ef312e/DJI_202508050138_002_15a21693-3d05-4923-b46d-90fc18ef312e/DJI_20250805014002_0001_V.jpeg");
|
|
|
var first64Kb = new byte[64 * 1024];
|
|
|
var bytesRead = y.Result.ReadAsync(first64Kb, 0, first64Kb.Length).Result;
|
|
|
var stream = new MemoryStream(first64Kb, 0, bytesRead);
|
|
|
stream.Position = 0;
|
|
|
y.Result.Position = 0;
|
|
|
// 从有限流中读取EXIF信息
|
|
|
var directories = ImageMetadataReader.ReadMetadata(y.Result);
|
|
|
int offset = 0, length = 0;
|
|
|
foreach (var directory in directories)
|
|
|
{
|
|
|
// 检查目录是否包含EXIF标签
|
|
|
if (directory is ExifDirectoryBase)
|
|
|
{
|
|
|
//Console.WriteLine(directory.Name);
|
|
|
if (directory.Name.Equals("Exif Thumbnail"))
|
|
|
{
|
|
|
foreach (var tag in directory.Tags)
|
|
|
{
|
|
|
if (tag.Name.Equals("Thumbnail Offset"))
|
|
|
{
|
|
|
offset = int.Parse(tag.Description.Replace("bytes", "").Trim());
|
|
|
}
|
|
|
|
|
|
if (tag.Name.Equals("Thumbnail Length"))
|
|
|
{
|
|
|
length = int.Parse(tag.Description.Replace("bytes", "").Trim());
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
/*foreach (var tag in directory.Tags)
|
|
|
{
|
|
|
if (tag.Name.Equals("Exif Thumbnail"))
|
|
|
{
|
|
|
offset = tag.Description;
|
|
|
}
|
|
|
Console.WriteLine($"{tag.Name}: {tag.Description} { tag.DirectoryName}");
|
|
|
}*/
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// todo 读取缩略图
|
|
|
// 提取缩略图数据
|
|
|
byte[] thumbnailData = new byte[length];
|
|
|
y.Result.Position = 0;
|
|
|
bytesRead = y.Result.ReadAsync(first64Kb, 0, first64Kb.Length).Result;
|
|
|
Console.WriteLine("读取的字节长度: " + bytesRead);
|
|
|
Array.Copy(first64Kb, offset + 6, thumbnailData, 0, length);
|
|
|
// 保存缩略图文件
|
|
|
File.WriteAllBytes("f:/ab.jpeg", thumbnailData);
|
|
|
}
|
|
|
|
|
|
// todo 完整图片尝试读取图片缩略图
|
|
|
// [Test]
|
|
|
public void TestGetThumbnail()
|
|
|
{
|
|
|
var picStr = "f:/DJI_20250805002929_0003_V.jpeg";
|
|
|
var directories = ImageMetadataReader.ReadMetadata(picStr);
|
|
|
int offset = 0, length = 0;
|
|
|
foreach (var directory in directories)
|
|
|
{
|
|
|
if (directory is ExifDirectoryBase)
|
|
|
{
|
|
|
//Console.WriteLine(directory.Name);
|
|
|
if (directory.Name.Equals("Exif Thumbnail"))
|
|
|
{
|
|
|
foreach (var tag in directory.Tags)
|
|
|
{
|
|
|
if (tag.Name.Equals("Thumbnail Offset"))
|
|
|
{
|
|
|
offset = int.Parse(tag.Description.Replace("bytes", "").Trim());
|
|
|
}
|
|
|
|
|
|
if (tag.Name.Equals("Thumbnail Length"))
|
|
|
{
|
|
|
length = int.Parse(tag.Description.Replace("bytes", "").Trim());
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
using (FileStream fileStream = new FileStream(picStr, FileMode.Open, FileAccess.Read))
|
|
|
{
|
|
|
fileStream.Seek(offset + 6, SeekOrigin.Begin);
|
|
|
byte[] buffer = new byte[length];
|
|
|
int bytesRead = fileStream.Read(buffer, 0, length);
|
|
|
var x = IsValidImageFormat(buffer);
|
|
|
Console.WriteLine("是否为有效图片:" + x);
|
|
|
Console.WriteLine("读取的字节长度: " + bytesRead);
|
|
|
File.WriteAllBytes("f:/ab.jpeg", buffer);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// [Test]
|
|
|
public void SaveTub()
|
|
|
{
|
|
|
var picStr = "f:/DJI_20250801170827_0082_V.jpeg";
|
|
|
var directories = ImageMetadataReader.ReadMetadata(picStr);
|
|
|
int offset = 0, length = 0;
|
|
|
}
|
|
|
|
|
|
//[Test]
|
|
|
public void ExtraceJpeg()
|
|
|
{
|
|
|
var picStr = "f:/DJI_20250801170827_0082_V.jpeg";
|
|
|
var extractor = new ExifThumbnailExtractor();
|
|
|
extractor.Extract(picStr, "f:/abc.jpeg");
|
|
|
}
|
|
|
|
|
|
private bool IsValidImageFormat(byte[] data)
|
|
|
{
|
|
|
if (data.Length < 2)
|
|
|
return false;
|
|
|
// JPEG以0xFFD8开头,TIFF以"II"或"MM"开头
|
|
|
bool isJpeg = data[0] == 0xFF && data[1] == 0xD8;
|
|
|
bool isTiff = (data[0] == 0x49 && data[1] == 0x49) || (data[0] == 0x4D && data[1] == 0x4D);
|
|
|
|
|
|
return isJpeg || isTiff;
|
|
|
}
|
|
|
|
|
|
[Test]
|
|
|
public void DownloadRange()
|
|
|
{
|
|
|
var minio = new MinioService();
|
|
|
long? picSize = 0;
|
|
|
int width = 0, height = 0, focalLength = 0;
|
|
|
int offset = 0, length = 0;
|
|
|
using (var httpClient = new HttpClient())
|
|
|
{
|
|
|
var total = 0L;
|
|
|
// 添加Range请求头
|
|
|
httpClient.DefaultRequestHeaders.Range = new System.Net.Http.Headers.RangeHeaderValue(0, 65535);
|
|
|
try
|
|
|
{
|
|
|
var response = httpClient
|
|
|
.GetAsync(
|
|
|
"http://" + minio.endPoint + "/" + minio._bucketName + "/" +
|
|
|
"/640aea27-2dd3-4081-933c-fcef432fcec0/71924889-540d-4362-aeb1-9ee787a655a7/DJI_202508050906_002_71924889-540d-4362-aeb1-9ee787a655a7/DJI_20250805090809_0001_V.jpeg",
|
|
|
HttpCompletionOption.ResponseHeadersRead).Result;
|
|
|
|
|
|
if (response.StatusCode == System.Net.HttpStatusCode.PartialContent)
|
|
|
{
|
|
|
//Focal Length 35: 24 mm
|
|
|
//Exif Image Width: 4032 pixels : Exif SubIFD
|
|
|
//Exif Image Height: 3024 pixels : Exif SubIFD
|
|
|
// 3.1 解析Content-Range头(格式:bytes start-end/total)
|
|
|
var contentRange = response.Content.Headers.ContentRange;
|
|
|
if (contentRange != null)
|
|
|
{
|
|
|
picSize = contentRange.Length;
|
|
|
Console.WriteLine($"获取范围:{contentRange.From}-{contentRange.To}/{contentRange.Length}");
|
|
|
}
|
|
|
|
|
|
// 成功获取部分内容
|
|
|
var y = response.Content.ReadAsByteArrayAsync().Result;
|
|
|
MemoryStream ms = new MemoryStream(y);
|
|
|
var directories = ImageMetadataReader.ReadMetadata(ms);
|
|
|
foreach (var directory in directories)
|
|
|
{
|
|
|
if (directory is ExifDirectoryBase)
|
|
|
{
|
|
|
foreach (var directoryTag in directory.Tags)
|
|
|
{
|
|
|
Console.WriteLine(
|
|
|
$"{directoryTag.Name}: {directoryTag.Description} : {directoryTag.DirectoryName}");
|
|
|
}
|
|
|
if (directory.Name.Equals("Exif SubIFD"))
|
|
|
{
|
|
|
foreach (var tag in directory.Tags)
|
|
|
{
|
|
|
if (tag.Name.Equals("Exif Image Width"))
|
|
|
{
|
|
|
width = int.Parse(tag.Description.Replace("pixels", "")
|
|
|
.Trim());
|
|
|
}
|
|
|
|
|
|
if (tag.Name.Equals("Exif Image Height"))
|
|
|
{
|
|
|
height = int.Parse(tag.Description.Replace("pixels", "")
|
|
|
.Trim());
|
|
|
}
|
|
|
|
|
|
if (tag.Name.Equals("Focal Length 35"))
|
|
|
{
|
|
|
focalLength = int.Parse(tag.Description.Replace("mm", "")
|
|
|
.Trim());
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
//Console.WriteLine(directory.Name);
|
|
|
if (directory.Name.Equals("Exif Thumbnail"))
|
|
|
{
|
|
|
foreach (var tag in directory.Tags)
|
|
|
{
|
|
|
if (tag.Name.Equals("Thumbnail Offset"))
|
|
|
{
|
|
|
offset = int.Parse(tag.Description.Replace("bytes", "").Trim());
|
|
|
}
|
|
|
|
|
|
if (tag.Name.Equals("Thumbnail Length"))
|
|
|
{
|
|
|
length = int.Parse(tag.Description.Replace("bytes", "").Trim());
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
var fileUpload = new LasaMediaFile()
|
|
|
{
|
|
|
Id = Guid.NewGuid().ToString(),
|
|
|
Width = width,
|
|
|
Height = height,
|
|
|
Size = picSize,
|
|
|
ShowOnMap = 1,
|
|
|
display = 1,
|
|
|
FocalLength = focalLength
|
|
|
};
|
|
|
Console.WriteLine("是否有错呢:" + JsonConvert.SerializeObject(fileUpload));
|
|
|
ms.Seek(offset + 6, SeekOrigin.Begin);
|
|
|
byte[] buffer = new byte[length];
|
|
|
int bytesRead = ms.Read(buffer, 0, length);
|
|
|
var x = IsValidImageFormat(buffer);
|
|
|
Console.WriteLine("是否为有效图片:" + x);
|
|
|
Console.WriteLine("读取的字节长度: " + bytesRead);
|
|
|
File.WriteAllBytes("f:/abbbbbb.jpeg", buffer);
|
|
|
}
|
|
|
else if (response.StatusCode == System.Net.HttpStatusCode.OK)
|
|
|
{
|
|
|
// 服务器不支持Range请求,返回完整内容
|
|
|
throw new InvalidOperationException("服务器不支持Range请求");
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
throw new HttpRequestException($"请求失败: {response.StatusCode}");
|
|
|
}
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
throw new Exception($"下载Range数据失败: {ex.Message}", ex);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
} |