1. 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++开发的。详细介绍和使用方法可参考官网。
3)EXIFTOOL BY PHIL HARVEY
同样是基于命令行的应用程序,但是是基于Perl语言的,可以读、写和编辑更多类型文件的元信息(meta information),甚至可以在EXIF中添加自定义的tag. 因本人没有尝试所以不能确定具体如何操作。详细介绍与使用可参考
3 EXIF格式
由于现在EXIF格式用得比较多,所以重点看一下EXIF的格式,具体参考,该网站上列出的EXIF的标签(tags)非常的全,并且有类型和描述,对于读取和修改EXIF的信息非常的有用。
4 编程实现EXIF信息的读取、修改和添加
在C#语言环境中对于图像元数据的读取和修改可通过GDI和WPF中的图像处理类库实现。
1)读取和修改
a)利用c# GDI+ 实现。
GDI和GDI+是微软的图形设备接口,具体的介绍可查询MSDN网站。在C# 中用GDI+实现对EXIF数据的读取和修改代码可参考下面这篇文章。
下面是本人参考网上资料所写代码。
修改或添加Exif中的tag的信息:
-
Image image = Image.FromFile(@"d:\1.jpg");
-
string comments = textEdit_writeInfo.Text;
-
PropertyItem pi = image.PropertyItems[0];
-
pi.Id = 37510;
-
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网站.
读取和修改EXIF信息的代码可参考下面的文章:
本方法基本思想是通过读取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))
-
{
-
-
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)
-
{
-
-
byte[] info = Encoding.Default.GetBytes(metadata.GetQuery("/app1/ifd/exif:{uint=37510}").ToString());
-
getinfo = Encoding.GetEncoding("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))
-
{
-
-
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)
-
{
-
-
metaData.SetQuery("/app1/ifd/exif:{uint=37510}", comments);
-
-
-
JpegBitmapEncoder encoder = new JpegBitmapEncoder();
-
encoder.Frames.Add(BitmapFrame.Create(bitmapFrame, bitmapFrame.Thumbnail, metaData, bitmapFrame.ColorContexts));
-
-
-
using (Stream jpegStreamOut = File.Open(imageFlePath, FileMode.Create, FileAccess.ReadWrite))
-
{
-
encoder.Save(jpegStreamOut);
-
}
-
}
-
}
-
}
-
}
2) 编程实现EXIF中Tag的添加
http://stackoverflow.com/questions/10833928/custom-exif-tags
没有找到很好的方法,本人采取将自定义数据写到User Comment标签中。
后来看到下面的方法,不过还没有尝试,不知道可不可行。
5 相关博文推荐
codeproject上看到的比较好的文章
stack overflow 上的一问答 ,回答里面推荐了codeproject上几篇比较好的文章,值得仔细阅读。
阅读(4387) | 评论(0) | 转发(0) |