简体   繁体   English

使用 c# 对 jpg 图像进行地理标记

[英]Geotag a jpg image with c#

How can I write the latitude and longitude in the metadata of a jpg file as shown in the following image如何在 jpg 文件的元数据中写入纬度和经度,如下图所示

元数据属性窗口

So far I have the following code but it does not work for me, I am using methods that extend the Bitmap class到目前为止,我有以下代码,但它对我不起作用,我正在使用扩展 Bitmap class 的方法

public static Bitmap WriteCoordinatesToImage(this Bitmap sourceBitmap, double latitude, double longitude)
    {
        byte[] bLatitude = BitConverter.GetBytes(latitude);
        byte[] bLongitude = BitConverter.GetBytes(longitude);

        PropertyItem prop = sourceBitmap.PropertyItems[0];
        prop.Id = 0x0002;
        prop.Type = 5;
        prop.Len = bLatitude.Length;
        prop.Value = bLongitude;
        sourceBitmap.SetPropertyItem(prop);

        prop.Id = 0x0004;
        prop.Type = 5;
        prop.Len = bLatitude.Length;
        prop.Value = bLatitude;
        sourceBitmap.SetPropertyItem(prop);

        return sourceBitmap;
    }

You will need to assign the proper EXIF tags.您将需要分配正确的 EXIF 标签。 I ran into this a while back and found a solution I liked.不久前我遇到了这个问题,并找到了我喜欢的解决方案。 Here is the code for it:这是它的代码:

There is of course libraries too, but this if all you need is geo this is pretty light weight.当然也有图书馆,但如果你只需要地理,那么这很轻。

using System.Drawing;
using System.Drawing.Imaging;


void Main()
{
    //How to use methods below
    Geotag(new Bitmap(@"D:\test.jpg"), 88, -169) // image location, latitude, longitude
    .Save(@"D:\geotaggedTest.jpg", ImageFormat.Jpeg);
}

// You can define other methods, fields, classes and namespaces here
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);
}

this produces:这会产生:

在此处输入图像描述

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM