C#在地图窗体中展示照片拍摄地点

标签: WinForm C#
发布时间: 2013/10/21 17:40:49

介绍 

这个windows桌面应用,以图片为输入参数。如果该图片含有GPS元数据,它将在谷歌地图中定位到拍摄该图片的位置(也可配置为其他地图网站或应用)。智能机在这方面的功能做的比较出色,但是一旦你将照片复制到台式或笔记本电脑中的话,想知道这些照片的拍摄地点就不是一件容易的事情了。如果图片的元数据中不包含GPS数据,或者输入的文件不是图片类型,就会弹出一个错误提示窗体,来显示错误的详细信息。为了使这个更易于使用,把它放到你的桌面,把图片拖拽到该可执行文件上,或者把它设置为图片的一种打开方式即可(查看普通图片那样)。

背景 

实现上述描述功能的代码在很多地方都可以得到:比如MSDN或者在CodeProject上。而这里呢,我将各个小模块进行了整合,做成了一个可用的实例。 

代码 

附件中的代码可直接编译运行,无需调试。如果你想扩展这些代码为自己所用,那么你需要特别留意以下两个封装好的,而且实现大部分功能的类文件Coord.cs 和 GeoPoint.cs。  
关键点的说明: 

  1. 在启动文件(Program.cs)中,我们通过解析命令行来指定有效的图形文件路径. 

  2. 在GeoPoint.GetFromImageFile()方法中,我们从图形的元数据中解析GPS详细信息. 

  3. 一旦我们获得GPS详细信息,我们使用Coord中的方法,把它们转换为完整的经纬度信息. 

  4. 在获得经纬度后,我们构造一个URL来打开谷歌地图,并定位到照片拍摄的位置。需要说明的是:你可以更改构造的URL来调用任何其他的地图网站实现定位,或者你获得坐标后,直接向你选择的地图中的API传递参数. 

  5. 我们将启动默认的浏览器来加载URL. 

兴趣点 

目前的数据中,经纬坐标这样的数据可能更实际化,因此Coord.ToGeoCode()这个方法我没有找到一个合适的测试用例,所以这次没有测试该方法。如果你找到了一个针对这个方法的测试用例,无论该方法是否好用,请直接告诉我,并且不用感觉到不自在。

扩展该代码


我觉得有些人可能会问,如何把这个功能添加到资源管理器的图片右键菜单中呢?这个简单,用SharpShell[^] (非常酷的一个项目——非常感谢SharpShell[^] 项目组)就可以实现了。至于细节,你可以详细的读一下SharpShell的文档。但是大体流程是:它将意味着在shell的上下文菜单添加一个菜单项。我以前在一个大型项目(以后将写成文章发表出来)中用到过这个东西。在那个项目中,该主题的相关内容只是那个项目的一个从属部分。因此可以大胆的说,这段代码没有问题。  

// The key piece of code to get the menu, or if not a valid picture file, null
private ToolStripMenuItem GetShowImageLocationMenu()
{
      // SelectedItemPaths is a property of SharpShell's SharpContextMenu
    string selected_file = SelectedItemPaths.FirstOrDefault();
     
    if (IsImage(selected_file))
    {
 
        var imageLocationRootMenu = new ToolStripMenuItem("Show Picture Location");
        imageLocationRootMenu.ToolTipText = "Show location picture was taken on a map.";
        imageLocationRootMenu.Click += new EventHandler((o, e) =>
        {
                    // On menu click, try to display the image locaion, or display errors if needed
            string messages = ShowPictureLocationLib.ShowPictureLocationHelper.ShowLocation(selected_file);
            if (!String.IsNullOrEmpty(messages))
            {
                Msg.Box(messages, "Alert", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
            }
        });
        return imageLocationRootMenu;
    }
    return null;
}
 
// Code to aid in identifying ExIF images
public static bool IsImage(string path_to_file)
{
    if (String.IsNullOrEmpty(path_to_file) || !File.Exists(path_to_file))
    {
        return false;
    }
 
    // Extensions based on this article:
    // http://en.wikipedia.org/wiki/Exchangeable_image_file_format
    return (new string[] { "jpg", "jpeg", "png", "tiff", "gif" })
        .Contains(
            (new FileInfo(path_to_file)).Extension.TrimStart('.').ToLower()
        );
}


官方微信
官方QQ群
31647020