读取和修改JPEG图片文件的头信息EXIF和JFIF

  • JPEG图片格式的发展历程和简单介绍可参考下面的文章
    http://en.wikipedia.org/wiki/JPEG
  • http://blog.csdn.net/kickxxx/article/details/8173332

    1. 读取JPEG图片文件头信息的工具
      从上文中可以知道JPEG有两种格式即JFIF和EXIF,现在数码相机为了添加一些附加信息如相机厂家,相机型号等信息多采用EXIF格式的,而需要时实传输数据的相机则多采用节省字节的JFIF格式。目前也有很工具可以辅助我们来读取JFIF 和 EXIF中的附加信息。下面介绍几个小工具。

    1)JHEAD
    基于DOS命令行的一款软件,可以读取JPEG图片中的JFIF和EXIF信息,可以修改EXIF信息,注意不能修改该图片的EXIF中没有的标签项,也不能修改JFIF中的信息。最大的优点是可以批量处理。使用时注意将JHEAD.EXE与图片放在同一路径下。具体命令格式参考下面这篇博文。

    http://blog.csdn.net/geekcome/article/details/6385142

    2)EXIV2
    EXIV2同样是基于命令行的用来修改图像元信息(meta information)的软件,是用C++开发的。详细介绍和使用方法可参考官网http://www.exiv2.org/index.html。

    3)EXIFTOOL BY PHIL HARVEY
    同样是基于命令行的应用程序,但是是基于Perl语言的,可以读、写和编辑更多类型文件的元信息(meta information),甚至可以在EXIF中添加自定义的tag. 因本人没有尝试所以不能确定具体如何操作。详细介绍与使用可参考http://www.sno.phy.queensu.ca/~phil/exiftool/

    3 EXIF格式
    由于现在EXIF格式用得比较多,所以重点看一下EXIF的格式,具体参考http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/EXIF.html,该网站上列出的EXIF的标签(tags)非常的全,并且有类型和描述,对于读取和修改EXIF的信息非常的有用。

    4 编程实现EXIF信息的读取、修改和添加
    在C#语言环境中对于图像元数据的读取和修改可通过GDI和WPF中的图像处理类库实现。

    1)读取和修改
    a)利用c# GDI+ 实现。

    GDI和GDI+是微软的图形设备接口,具体的介绍可查询MSDN网站。在C# 中用GDI+实现对EXIF数据的读取和修改代码可参考下面这篇文章。

    http://www.news2news.com/vfp/?example=461&ver=vcs&PHPSESSID=bf05b446c2fcc58f5753c45fdaeb2402

    下面是本人参考网上资料所写代码。

    修改或添加Exif中的tag的信息:

    Image image = Image.FromFile(@“d:\1.jpg”);
    string comments = textEdit_writeInfo.Text;
    PropertyItem pi = image.PropertyItems[0];
    pi.Id = 37510;//想要修改的tag的id,如果该id没有定义则添加一个新的tag
    pi.Type = 7;
    pi.Value = Encoding.GetEncoding(“ascii”).GetBytes(comments);//将字符串转成字节数组
    pi.Len = pi.Value.Length;
    image.SetPropertyItem(pi);

    image.Save(@“d:\temp.jpg”);
    image.Dispose();

    读取Exif中某一tag的信息:

    Image image = Image.FromFile(@“d:\temp.jpg”);

    PropertyItem pi = image.GetPropertyItem(37510);
    getinfo = Encoding.GetEncoding(“ascii”).GetString(pi.Value);
    image.Dispose();

    b)借用WPF图像处理组件。

    WPF是微软开发的图像处理组件,通过WPF可以显示、转换图像和设置图像的格式,具体介绍参考MSDN网站http://msdn.microsoft.com/zh-cn/library/ms748873(v=vs.110).aspx.

    读取和修改EXIF信息的代码可参考下面的文章:

    http://www.codeproject.com/Articles/66328/Enumerating-all-of-the-Metadata-Tags-in-an-Image-F

    http://www.i-programmer.info/programming/wpf-workings/588-bitmap-codingencoding-and-working-with-metadata.html?start=2

    本方法基本思想是通过读取bitmap图像的基本信息来获得所需要的头信息,以及通过写入bitmap的基本信息来修改相应的图片头信息,中间要涉及到位图的编码和解码问题,所以耗时比较多。

    代码如下:

    读取:

    public string extractComment(string imageFilePath)
    {
    string getinfo = “”;
    string jpegDirectory = Path.GetDirectoryName(imageFilePath);
    string jpegFileName = Path.GetFileNameWithoutExtension(imageFilePath);

            BitmapDecoder decoder = null;
            BitmapFrame bitmapFrame = null;
            BitmapMetadata metadata = null;
            FileInfo originalImage = new FileInfo(imageFilePath);
    
        if (File.Exists(imageFilePath))
        {
            // load the jpg file with a JpegBitmapDecoder    
            using (Stream jpegStreamIn = File.Open(imageFilePath, FileMode.Open, FileAccess.ReadWrite, FileShare.None))
            {
                decoder = new JpegBitmapDecoder(jpegStreamIn, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.OnLoad);
            }
    
            bitmapFrame = decoder.Frames[0];
            metadata = (BitmapMetadata)bitmapFrame.Metadata;
    
            if (bitmapFrame != null)
            {
                BitmapMetadata metaData = (BitmapMetadata)bitmapFrame.Metadata.Clone();
    
                if (metaData != null)
                {
                    // read the metadata   
                    byte[] info = Encoding.Default.GetBytes(metadata.GetQuery("/app1/ifd/exif:{uint=37510}").ToString());
                    getinfo = Encoding.GetEncoding("ascii").GetString(info);// getinfo = Encoding.ASCII.GetString(info);
                }
            }
        }
        return getinfo;
    }
    

    修改或添加:

    public void addImageComment(string imageFlePath, string comments)
    {
    string jpegDirectory = Path.GetDirectoryName(imageFlePath);
    string jpegFileName = Path.GetFileNameWithoutExtension(imageFlePath);

            BitmapDecoder decoder = null;
            BitmapFrame bitmapFrame = null;
            BitmapMetadata metadata = null;
            if (File.Exists(imageFlePath))
            {
                // load the jpg file with a JpegBitmapDecoder    
                using (Stream jpegStreamIn = File.Open(imageFlePath, FileMode.Open, FileAccess.ReadWrite, FileShare.None))
                {
                    decoder = new JpegBitmapDecoder(jpegStreamIn, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.OnLoad);
                }
    
            bitmapFrame = decoder.Frames[0];
            metadata = (BitmapMetadata)bitmapFrame.Metadata;
    
            if (bitmapFrame != null)
            {
                BitmapMetadata metaData = (BitmapMetadata)bitmapFrame.Metadata.Clone();
    
                if (metaData != null)
                {
                    // modify the metadata   
                  metaData.SetQuery("/app1/ifd/exif:{uint=37510}", comments);//comment
    
                    // get an encoder to create a new jpg file with the new metadata.      
                    JpegBitmapEncoder encoder = new JpegBitmapEncoder();
                    encoder.Frames.Add(BitmapFrame.Create(bitmapFrame, bitmapFrame.Thumbnail, metaData, bitmapFrame.ColorContexts));
    
                    // Save the new image 
                    using (Stream jpegStreamOut = File.Open(imageFlePath, FileMode.Create, FileAccess.ReadWrite))
                    {
                        encoder.Save(jpegStreamOut);
                    }
                }
            }
        }
    }
    

    2) 编程实现EXIF中Tag的添加
    http://www.velocityreviews.com/threads/add-exif-tag-to-jpeg.258124/

    http://stackoverflow.com/questions/10833928/custom-exif-tags

    没有找到很好的方法,本人采取将自定义数据写到User Comment标签中。

    后来看到下面的方法,不过还没有尝试,不知道可不可行。

    http://geekswithblogs.net/nuri/archive/2012/01/25/of-image-exif-propertyitem-and-reflection.aspx
    5 相关博文推荐
    codeproject上看到的比较好的文章http://www.codeproject.com/Articles/43665/ExifLibrary-for-NET

    stack overflow 上的一问答http://stackoverflow.com/questions/226973/how-to-edit-exif-data-in-net?answertab=active#tab-top ,回答里面推荐了codeproject上几篇比较好的文章,值得仔细阅读。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值