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

1. JPEG图片格式的发展历程和简单介绍可参考下面的文章

http://en.wikipedia.org/wiki/JPEG

http://blog.csdn.net/kickxxx/article/details/8173332

2. 读取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标签中。

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

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上几篇比较好的文章,值得仔细阅读。


 

 



评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值