Merge remote-tracking branch 'origin/main'
commit
dbf58ef741
|
|
@ -0,0 +1,194 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Infrastructure.Helpers
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
public class ExifReader
|
||||
{
|
||||
// Exif 标签ID与名称的映射字典(部分常见标签)
|
||||
private static readonly Dictionary<int, string> ExifTags = new Dictionary<int, string>
|
||||
{
|
||||
{ 0x010E, "ImageDescription" },
|
||||
{ 0x010F, "Make" },
|
||||
{ 0x0110, "Model" },
|
||||
{ 0x0112, "Orientation" },
|
||||
{ 0x011A, "XResolution" },
|
||||
{ 0x011B, "YResolution" },
|
||||
{ 0x0128, "ResolutionUnit" },
|
||||
{ 0x0131, "Software" },
|
||||
{ 0x0132, "DateTime" },
|
||||
{ 0x0213, "YCbCrPositioning" },
|
||||
{ 0x8769, "ExifIFD" },
|
||||
{ 0x829A, "ExposureTime" },
|
||||
{ 0x829D, "FNumber" },
|
||||
{ 0x8822, "ExposureProgram" },
|
||||
{ 0x8827, "ISOSpeedRatings" },
|
||||
{ 0x9000, "ExifVersion" },
|
||||
{ 0x9003, "DateTimeOriginal" },
|
||||
{ 0x9004, "DateTimeDigitized" },
|
||||
{ 0x9101, "ComponentsConfiguration" },
|
||||
{ 0x9201, "ShutterSpeedValue" },
|
||||
{ 0x9202, "ApertureValue" },
|
||||
{ 0x9203, "BrightnessValue" },
|
||||
{ 0x9204, "ExposureBiasValue" },
|
||||
{ 0x9205, "MaxApertureValue" },
|
||||
{ 0x9206, "SubjectDistance" },
|
||||
{ 0x9207, "MeteringMode" },
|
||||
{ 0x9208, "LightSource" },
|
||||
{ 0x9209, "Flash" },
|
||||
{ 0x920A, "FocalLength" },
|
||||
{ 0x927C, "MakerNote" },
|
||||
{ 0x9286, "UserComment" },
|
||||
{ 0x9290, "SubsecTime" },
|
||||
{ 0x9291, "SubsecTimeOriginal" },
|
||||
{ 0x9292, "SubsecTimeDigitized" },
|
||||
{ 0xA000, "FlashpixVersion" },
|
||||
{ 0xA001, "ColorSpace" },
|
||||
{ 0xA002, "PixelXDimension" },
|
||||
{ 0xA003, "PixelYDimension" },
|
||||
{ 0xA004, "RelatedSoundFile" },
|
||||
{ 0xA005, "InteroperabilityIFD" },
|
||||
{ 0xA20B, "FlashEnergy" },
|
||||
{ 0xA20C, "SpatialFrequencyResponse" },
|
||||
{ 0xA20E, "FocalPlaneXResolution" },
|
||||
{ 0xA20F, "FocalPlaneYResolution" },
|
||||
{ 0xA210, "FocalPlaneResolutionUnit" },
|
||||
{ 0xA214, "SubjectLocation" },
|
||||
{ 0xA215, "ExposureIndex" },
|
||||
{ 0xA217, "SensingMethod" },
|
||||
{ 0xA300, "FileSource" },
|
||||
{ 0xA301, "SceneType" },
|
||||
{ 0xA302, "CFAPattern" },
|
||||
{ 0xA401, "CustomRendered" },
|
||||
{ 0xA402, "ExposureMode" },
|
||||
{ 0xA403, "WhiteBalance" },
|
||||
{ 0xA404, "DigitalZoomRatio" },
|
||||
{ 0xA405, "FocalLengthIn35mmFilm" },
|
||||
{ 0xA406, "SceneCaptureType" },
|
||||
{ 0xA407, "GainControl" },
|
||||
{ 0xA408, "Contrast" },
|
||||
{ 0xA409, "Saturation" },
|
||||
{ 0xA40A, "Sharpness" },
|
||||
{ 0xA40B, "DeviceSettingDescription" },
|
||||
{ 0xA40C, "SubjectDistanceRange" },
|
||||
{ 0xA420, "ImageUniqueID" },
|
||||
{ 0xA431, "BodySerialNumber" },
|
||||
{ 0xA432, "LensSpecification" },
|
||||
{ 0xA433, "LensMake" },
|
||||
{ 0xA434, "LensModel" },
|
||||
{ 0xA435, "LensSerialNumber" },
|
||||
{ 0x8298, "Copyright" }, // 这是你特别关心的 Copyright 字段
|
||||
{ 0x013B, "Artist" },
|
||||
{ 0x9C9B, "WindowsTitle" },
|
||||
{ 0x9C9C, "WindowsComment" },
|
||||
{ 0x9C9D, "WindowsAuthor" },
|
||||
{ 0x9C9E, "WindowsKeywords" },
|
||||
{ 0x9C9F, "WindowsSubject" }
|
||||
};
|
||||
|
||||
public static Dictionary<string, string> GetAllExifData(Stream imageStream)
|
||||
{
|
||||
var exifData = new Dictionary<string, string>();
|
||||
|
||||
using (Image image = Image.FromStream(imageStream))
|
||||
{
|
||||
foreach (PropertyItem propItem in image.PropertyItems)
|
||||
{
|
||||
string tagName = ExifTags.ContainsKey(propItem.Id) ?
|
||||
ExifTags[propItem.Id] : $"Unknown (0x{propItem.Id:X4})";
|
||||
|
||||
string value = InterpretExifValue(propItem);
|
||||
exifData[tagName] = value;
|
||||
}
|
||||
}
|
||||
|
||||
return exifData;
|
||||
}
|
||||
|
||||
private static string InterpretExifValue(PropertyItem propItem)
|
||||
{
|
||||
try
|
||||
{
|
||||
switch (propItem.Type)
|
||||
{
|
||||
case 1: // Byte array
|
||||
return $"Byte[{propItem.Len}]";
|
||||
|
||||
case 2: // ASCII string
|
||||
return Encoding.ASCII.GetString(propItem.Value).TrimEnd('\0');
|
||||
|
||||
case 3: // Unsigned short (16-bit)
|
||||
if (propItem.Len == 2)
|
||||
return BitConverter.ToUInt16(propItem.Value, 0).ToString();
|
||||
break;
|
||||
|
||||
case 4: // Unsigned long (32-bit)
|
||||
if (propItem.Len == 4)
|
||||
return BitConverter.ToUInt32(propItem.Value, 0).ToString();
|
||||
break;
|
||||
|
||||
case 5: // Unsigned rational (two 32-bit values: numerator/denominator)
|
||||
if (propItem.Len == 8)
|
||||
{
|
||||
uint numerator = BitConverter.ToUInt32(propItem.Value, 0);
|
||||
uint denominator = BitConverter.ToUInt32(propItem.Value, 4);
|
||||
return denominator != 0 ? $"{numerator}/{denominator}" : "Invalid rational";
|
||||
}
|
||||
break;
|
||||
|
||||
case 7: // Undefined
|
||||
return $"Undefined[{propItem.Len}]";
|
||||
|
||||
case 9: // Signed long (32-bit)
|
||||
if (propItem.Len == 4)
|
||||
return BitConverter.ToInt32(propItem.Value, 0).ToString();
|
||||
break;
|
||||
|
||||
case 10: // Signed rational (two 32-bit values: numerator/denominator)
|
||||
if (propItem.Len == 8)
|
||||
{
|
||||
int numerator = BitConverter.ToInt32(propItem.Value, 0);
|
||||
int denominator = BitConverter.ToInt32(propItem.Value, 4);
|
||||
return denominator != 0 ? $"{numerator}/{denominator}" : "Invalid rational";
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return $"Type {propItem.Type}[{propItem.Len}]";
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return $"Error reading value: {ex.Message}";
|
||||
}
|
||||
}
|
||||
|
||||
// 专门获取 Copyright 信息的方法
|
||||
public static string GetCopyright(Stream imageStream)
|
||||
{
|
||||
using (Image image = Image.FromStream(imageStream))
|
||||
{
|
||||
try
|
||||
{
|
||||
// 0x8298 是 Copyright 的 Exif tag ID
|
||||
PropertyItem copyrightProp = image.GetPropertyItem(0x8298);
|
||||
return InterpretExifValue(copyrightProp);
|
||||
}
|
||||
catch (ArgumentException)
|
||||
{
|
||||
// 如果没有找到 Copyright 属性
|
||||
return "No copyright information";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -39,11 +39,15 @@ namespace OpenAuth.App.ServiceApp.Algo
|
|||
{
|
||||
using (var db = UnitWork.CreateContext())
|
||||
{
|
||||
var imageList1 = await db.LasaMediaFile.AsQueryable().Where(r => r.TaskId == firstId && r.AbsoluteAltitude != 0 && r.AbsoluteAltitude != null).OrderBy(r=>r.CreateTime).ToListAsync();
|
||||
var imageList1 = await db.LasaMediaFile.AsQueryable().Where(r => r.TaskId == firstId && r.AbsoluteAltitude != 0 && r.AbsoluteAltitude != null).OrderBy(r => r.CreateTime).ToListAsync();
|
||||
var imageList2 = await db.LasaMediaFile.AsQueryable().Where(r => r.TaskId == secondId && r.AbsoluteAltitude != 0 && r.AbsoluteAltitude != null).OrderBy(r => r.CreateTime).ToListAsync();
|
||||
//var imageList1 = await db.LasaMediaFile.AsQueryable().Where(r => r.Id == firstId && r.AbsoluteAltitude != 0 && r.AbsoluteAltitude != null).ToListAsync();
|
||||
//var imageList2 = await db.LasaMediaFile.AsQueryable().Where(r => r.Id == secondId && r.AbsoluteAltitude != 0 && r.AbsoluteAltitude != null).ToListAsync();
|
||||
List<dynamic> dataList = new List<dynamic>();
|
||||
if (imageList1.Count() != imageList2.Count())
|
||||
{
|
||||
throw new Exception("任务照片数量不对应,请重新选择任务");
|
||||
}
|
||||
for (int i = 0; i < imageList1.Count; i++)
|
||||
{
|
||||
dataList.Add(new
|
||||
|
|
@ -215,7 +219,7 @@ namespace OpenAuth.App.ServiceApp.Algo
|
|||
}
|
||||
//public async Task<string> DrawingImgAndUpload(string url, int[][] regionArray)
|
||||
public async Task<string> DrawingImgAndUpload(string url, int[][] regionArray, string cdid)
|
||||
{
|
||||
{
|
||||
//string url = "http://123.132.248.154:6015/DroneEnforcement/2025/20250514/lQLPJyIVimQWGKnNA4PNA6Gw1D3q5gbxUvQIiumcIx4vAA_929_899.png";
|
||||
|
||||
// detectRegion JSON(可以直接替换成你的接口返回数据)
|
||||
|
|
|
|||
|
|
@ -26,6 +26,8 @@ using System.Text.Json;
|
|||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using System.Net;
|
||||
using System.Drawing.Imaging;
|
||||
using System.Drawing;
|
||||
|
||||
namespace OpenAuth.App.ServiceApp.DroneDocking
|
||||
{
|
||||
|
|
@ -1237,12 +1239,13 @@ namespace OpenAuth.App.ServiceApp.DroneDocking
|
|||
for (int i = 0; i < filigtlist.Count; i++)
|
||||
{
|
||||
var flightid = filigtlist[i];
|
||||
string fligthpicsql = "select * from lasa_mediafile where \"FlightId\"='" + flightid.flighttaskid +
|
||||
"'";
|
||||
string fligthpicsql = "select * from lasa_mediafile where \"FlightId\"='" + flightid.flighttaskid +"'";
|
||||
var pics = _client.Ado.SqlQuery<LasaMediaFile>(fligthpicsql);
|
||||
for (int j = 0; j < pics.Count; j++)
|
||||
{
|
||||
var pic = pics[j];
|
||||
|
||||
#region 筛选.jpeg图片,添加exif信息,转byte
|
||||
if (pic.ObjectKey==null||!pic.ObjectKey.EndsWith(".jpeg"))
|
||||
{
|
||||
continue;
|
||||
|
|
@ -1252,21 +1255,45 @@ namespace OpenAuth.App.ServiceApp.DroneDocking
|
|||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
byte[] bytes;
|
||||
using (MemoryStream memoryStream = new MemoryStream())
|
||||
using (var image = Image.FromStream(await imageStream))
|
||||
{
|
||||
imageStream.Result.CopyTo(memoryStream); // 将原始流复制到MemoryStream中
|
||||
bytes = memoryStream.ToArray(); // 获取MemoryStream的字节数组表示
|
||||
}
|
||||
// 获取属性项列表(如果不存在则创建)
|
||||
if (image.PropertyIdList.Contains(0x8298)) // 0x8298 是 Copyright 的 Exif tag ID
|
||||
{
|
||||
// 移除现有的 Copyright 信息(可选)
|
||||
image.RemovePropertyItem(0x8298);
|
||||
}
|
||||
|
||||
// 创建新的属性项
|
||||
PropertyItem propItem = image.PropertyItems[0];
|
||||
propItem.Id = 0x8298; // Copyright tag
|
||||
propItem.Type = 2; // ASCII 类型
|
||||
propItem.Value = System.Text.Encoding.ASCII.GetBytes("UAV32_LJY2FPMYDE6UDES3P3ZD7V3IKQ"); // 以 null 结尾的字符串
|
||||
propItem.Len = propItem.Value.Length;
|
||||
|
||||
// 设置属性
|
||||
image.SetPropertyItem(propItem);
|
||||
|
||||
using (MemoryStream memoryStream = new MemoryStream())
|
||||
{
|
||||
image.Save(memoryStream, ImageFormat.Jpeg); ; // 将原始流复制到MemoryStream中
|
||||
bytes = memoryStream.ToArray(); // 获取MemoryStream的字节数组表示
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 图片转hash
|
||||
//转hash
|
||||
string fileHash;
|
||||
SM3Digest digest = new SM3Digest();
|
||||
digest.BlockUpdate(bytes, 0, bytes.Length);
|
||||
byte[] resultss = new byte[digest.GetDigestSize()];
|
||||
digest.DoFinal(resultss, 0);
|
||||
fileHash = Hex.ToHexString(resultss).ToUpper();
|
||||
#endregion
|
||||
|
||||
#region 将数据写入FJ表
|
||||
string sqlintoFj =
|
||||
"INSERT INTO FJ (BSM, DKLX, DKBSM, ZDKBH, XZQDM, FJMC, FJLX, PSTZ, FJ, FJHXZ, PSSJ, XDGD, JDGD, Longitude, Latitude, PSFYJ, PSJD, PSHGJ, PSJJ, FJYSKD, FJYSGD, PSDXZXX, PSRY, SPKZXX, ZSDM, JYM) " +
|
||||
"VALUES (@BSM, @DKLX, @DKBSM, @ZDKBH, @XZQDM, @FJMC, @FJLX, @PSTZ, @FJ, @FJHXZ, @PSSJ, @XDGD, @JDGD, @Longitude, @Latitude, @PSFYJ, @PSJD, @PSHGJ, @PSJJ, @FJYSKD, @FJYSGD, @PSDXZXX, @PSRY, @SPKZXX, @ZSDM, @JYM)";
|
||||
|
|
@ -1340,6 +1367,7 @@ namespace OpenAuth.App.ServiceApp.DroneDocking
|
|||
cmd.ExecuteNonQuery();
|
||||
totalcount += 1;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -3,10 +3,10 @@
|
|||
"code": "AirportData",
|
||||
"count": "0",
|
||||
"extension": "db",
|
||||
"hash": "83A747C4E7E4244F54B0D449811DD815FC375AFD3A5EDAA98258250CE91F4A98",
|
||||
"hash": "7BBA4C0E5D91B3B59E914A22EA69BA3ED4254600D75E06E1542263BBA3DC5285",
|
||||
"regioncode": "370000",
|
||||
"sign": "8D7440C34D89FF079DAA6FC74BFFDA5A5DE938F57A016E7639327AC0685327A90289DDA94317C3ADC64FFEA88EFF4C1FCA145629EA17FCCA6C42F5A136E817D6",
|
||||
"size": "42568704",
|
||||
"timestamp": "1757491062",
|
||||
"sign": "1382A20972741FACB09DDB70D00CA6055D0C7DCB59A1E43A7177E13FA17E399F201A6928CFFDEA755B6059606712DFDC800B9AF985DE56C55D1B3027D2ACD12F",
|
||||
"size": "40065024",
|
||||
"timestamp": "1757497088",
|
||||
"version": "1"
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue