当前位置:   GIT > 正文

如何添加EXIF信息以在.NET中对图像进行地理标记?

.net,exif,image,geotagging,c#,git,DevBox,在线流程图,编程,编程问答,程序员,开发者工具,开发工具,json解析,二维码生成,unix时间戳,在线开发工具,前端开发工具,开发人员工具,站长工具

我在.NET中有一个Image.如何通过使用EXIF数据对其生成的纬度和经度进行编码来对图像进行地理标记,但无需使用外部库?



1> Ben..:

可以使用PropertyItems将EXIF信息附加到.NET 2.0及更高版本中的映像,PropertyItems可转换为单个EXIF字段.这些字段的详细信息可以在EXIF 2.3标准中找到,但我们只需要其中五个来对图像进行地理标记.下面的示例C#代码需要引用System.Drawing,System.Drawing.Imaging和System.IO.要测试它,只需使用下面的行.您可以通过使用此工具(或许多其他工具之一)检查图像来验证图像是否已正确地进行了地理标记.

Geotag(new Bitmap(@"C:\path\to\image.jpg"), 34, -118)
    .Save(@"C:\path\to\geotagged.jpg", ImageFormat.Jpeg);

下面的代码可能看起来很奇怪的一件事是,PropertyItem被重用来创建一个新的PropertyItem.由于改变现有的PropertyItem(它是一个类而不是一个struct)似乎会影响现有的属性,因此这种方法并不明显.然而,事实证明并非如此,并且这个hack是必要的,因为PropertyItem没有公共构造函数.

static Image Geotag(Image original, double lat, double lng)
{
    // These constants come from the CIPA DC-008 standard for EXIF 2.3
    const short ExifTypeByte = 1;
    const short ExifTypeAscii = 2;
    const short ExifTypeRational = 5;

    const int ExifTagGPSVersionID = 0x0000;
    const int ExifTagGPSLatitudeRef = 0x0001;
    const int ExifTagGPSLatitude = 0x0002;
    const int ExifTagGPSLongitudeRef = 0x0003;
    const int ExifTagGPSLongitude = 0x0004;

    char latHemisphere = 'N';
    if (lat < 0)
    {
        latHemisphere = 'S';
        lat = -lat;
    }
    char lngHemisphere = 'E';
    if (lng < 0)
    {
        lngHemisphere = 'W';
        lng = -lng;
    }

    MemoryStream ms = new MemoryStream();
    original.Save(ms, ImageFormat.Jpeg);
    ms.Seek(0, SeekOrigin.Begin);

    Image img = Image.FromStream(ms);
    AddProperty(img, ExifTagGPSVersionID, ExifTypeByte, new byte[] { 2, 3, 0, 0 });
    AddProperty(img, ExifTagGPSLatitudeRef, ExifTypeAscii, new byte[] { (byte)latHemisphere, 0 });
    AddProperty(img, ExifTagGPSLatitude, ExifTypeRational, ConvertToRationalTriplet(lat));
    AddProperty(img, ExifTagGPSLongitudeRef, ExifTypeAscii, new byte[] { (byte)lngHemisphere, 0 });
    AddProperty(img, ExifTagGPSLongitude, ExifTypeRational, ConvertToRationalTriplet(lng));

    return img;
}

static byte[] ConvertToRationalTriplet(double value)
{
    int degrees = (int)Math.Floor(value);
    value = (value - degrees) * 60;
    int minutes = (int)Math.Floor(value);
    value = (value - minutes) * 60 * 100;
    int seconds = (int)Math.Round(value);
    byte[] bytes = new byte[3 * 2 * 4]; // Degrees, minutes, and seconds, each with a numerator and a denominator, each composed of 4 bytes
    int i = 0;
    Array.Copy(BitConverter.GetBytes(degrees), 0, bytes, i, 4); i += 4;
    Array.Copy(BitConverter.GetBytes(1), 0, bytes, i, 4); i += 4;
    Array.Copy(BitConverter.GetBytes(minutes), 0, bytes, i, 4); i += 4;
    Array.Copy(BitConverter.GetBytes(1), 0, bytes, i, 4); i += 4;
    Array.Copy(BitConverter.GetBytes(seconds), 0, bytes, i, 4); i += 4;
    Array.Copy(BitConverter.GetBytes(100), 0, bytes, i, 4);
    return bytes;
}

static void AddProperty(Image img, int id, short type, byte[] value)
{
    PropertyItem pi = img.PropertyItems[0];
    pi.Id = id;
    pi.Type = type;
    pi.Len = value.Length;
    pi.Value = value;
    img.SetPropertyItem(pi);
}

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/blog/GIT/detail/12837
推荐阅读
  • 如何解决《Docker-composeup不会启动容器》经验,为你挑选了1个好方法。docker,docker-compose,ruby,git,npm,bash,ssh,go,容器,服务器,DevBox,在线流程图,编程,编程问答,程序员... [详细]

  • 如何解决《#define宏用于C中的调试打印?》经验,为你挑选了7个好方法。c,c-preprocessor,程序员,go,git,注入,html,DevBox,在线流程图,编程,编程问答,程序员,开发者工具,开发工具,json解析,二维码... [详细]

  • 如何解决《git拉在另一个分支上》经验,为你挑选了2个好方法。git,DevBox,在线流程图,编程,编程问答,程序员,开发者工具,开发工具,json解析,二维码生成,unix时间戳,在线开发工具,前端开发工具,开发人员工具,站长工具如果我... [详细]

  • 如何解决《使用'bool'而不是'Boolean'的JQueryTypescript定义》经验,为你挑选了2个好方法。boolean,typescript,definitelytyped,jquery,htt... [详细]

  • 如何解决《Angular2快速入门:意外令牌<》经验,为你挑选了3个好方法。javascript,angular,npm,lua,bootstrap,html,json,typescript,服务器,chrome,https,git,... [详细]

  • 如何解决《为什么从已经上传的其他分支检出文件?》经验,为你挑选了2个好方法。git,DevBox,在线流程图,编程,编程问答,程序员,开发者工具,开发工具,json解析,二维码生成,unix时间戳,在线开发工具,前端开发工具,开发人员工具,... [详细]

  • 如何解决《Phoenix错误:模块未加载/不可用》经验,为你挑选了2个好方法。elixir,phoenix-framework,https,git,DevBox,在线流程图,编程,编程问答,程序员,开发者工具,开发工具,json解析,二维码... [详细]

  • 如何解决《如何从React路由器向链接添加活动类?》经验,为你挑选了5个好方法。react-router,bootstrap,https,git,css,vb,DevBox,在线流程图,编程,编程问答,程序员,开发者工具,开发工具,json... [详细]

  • 如何解决《MAC-我无法在Mac上打开Android设备监视器》经验,为你挑选了2个好方法。android,windows,eclipse,apache,ruby,https,git,DevBox,在线流程图,编程,编程问答,程序员,开发者... [详细]

  • 如何解决《Mercurial:Subrepo错误-"中止:提交新的subrepo[路径]排除"》经验,为你挑选了1个好方法。mercurial,subrepos,git,https,DevBox,在线流程图,编程,编程问... [详细]

  • 如何解决《在python中生成一个固定长度的随机字符串列表》经验,为你挑选了1个好方法。python,random,list,python-3.x,git,DevBox,在线流程图,编程,编程问答,程序员,开发者工具,开发工具,json解析... [详细]

  • 如何解决《由'ggpair'和'ggplot'并排生成的图》经验,为你挑选了2个好方法。r,ggplot2,https,git,go,DevBox,在线流程图,编程,编程问答,程序员,开发者工具,开发工具,j... [详细]

  • 如何解决《如何在BitBucket上创建文件夹?》经验,为你挑选了2个好方法。git,bitbucket,https,DevBox,在线流程图,编程,编程问答,程序员,开发者工具,开发工具,json解析,二维码生成,unix时间戳,在线开发... [详细]

  • 如何解决《`gitadd-p`的选项有哪些?》经验,为你挑选了1个好方法。git,git-add,jquery,go,DevBox,在线流程图,编程,编程问答,程序员,开发者工具,开发工具,json解析,二维码生成,unix时间戳,在线开发... [详细]

  • 如何解决《在基于buildout的Plone站点中使用非最新的gitcheckout》经验,为你挑选了1个好方法。git,plone,buildout,DevBox,在线流程图,编程,编程问答,程序员,开发者工具,开发工具,json解析,二... [详细]

  • 如何解决《如何用mercurial检查你所在的分支》经验,为你挑选了2个好方法。mercurial,branch,git,DevBox,在线流程图,编程,编程问答,程序员,开发者工具,开发工具,json解析,二维码生成,unix时间戳,在线... [详细]

  • 如何解决《Proguard和RxAndroidV1.1.0》经验,为你挑选了1个好方法。android,rx-java,rx-android,git,DevBox,在线流程图,编程,编程问答,程序员,开发者工具,开发工具,json解析,二维... [详细]

  • 如何解决《量角器测试是否可见模态》经验,为你挑选了1个好方法。javascript,twitter-bootstrap,angularjs,protractor,css,bootstrap,git,注入,DevBox,在线流程图,编程,编程... [详细]

  • 如何解决《将promisepolyfill添加到ES6》经验,为你挑选了1个好方法。javascript,promise,ecmascript-6,reactjs,npm,https,git,DevBox,在线流程图,编程,编程问答,程序员... [详细]

  • 如何解决《dnxcore50与dnx451的性能比较?(CoreClr与.netFramework)》经验,为你挑选了1个好方法。coreclr,dnx,asp.net-core,windows,asp.net,git,https,DevB... [详细]

相关标签
  

闽ICP备14008679号