数码相机的照片很多,而且文件名也不直观,所以写了个程序批量改名,就是把文件名都改成相机的拍照日期,呵呵,谁知道拍照日期不是那么好取,在csdn里开了一帖,谢谢网友帮忙,终于搞定!把代码放在下面了,说不定谁会用得着。
原帖地址:http://community.csdn.net/expert/topic/4295/4295730.xml?temp=.662182
原文地址:http://www.codeproject.com/csharp/exifextractor.asp
////调用
string strfile=”fffff.jpg”;//文件名
system.drawing.bitmap bmp = new bitmap(strfile);
exif.exifextractor er = new exif.exifextractor(ref bmp, “\n”);
console.write(strfile + “\r\n”);
console.write(er[“dtdigitized”]);//拍照日期
foreach (exif.pair pr in er)
{
console.write(pr.first + “:” + pr.second + “\r\n”);
}
//////////////////////////////////////////////////////////////////////////////////////
///下面的两个文件处理jpg的exif信息
///exifextractor.cs
///
using system;
using system.text;
using system.collections;
using system.drawing.imaging;
using system.reflection;
using system.io;
namespace exif
{
/// <summary>
/// exifextractor class
///
/// </summary>
public class exifextractor : ienumerable
{
/// <summary>
/// get the individual property value by supplying property name
/// these are the valid property names :
///
/// “exif ifd”
/// “gps ifd”
/// “new subfile type”
/// “subfile type”
/// “image width”
/// “image height”
/// “bits per sample”
/// “compression”
/// “photometric interp”
/// “thresh holding”
/// “cell width”
/// “cell height”
/// “fill order”
/// “document name”
/// “image description”
/// “equip make”
/// “equip model”
/// “strip offsets”
/// “orientation”
/// “samples perpixel”
/// “rows per strip”
/// “strip bytes count”
/// “min sample value”
/// “max sample value”
/// “x resolution”
/// “y resolution”
/// “planar config”
/// “page name”
/// “x position”
/// “y position”
/// “free offset”
/// “free byte counts”
/// “gray response unit”
/// “gray response curve”
/// “t4 option”
/// “t6 option”
/// “resolution unit”
/// “page number”
/// “transfer funcition”
/// “software used”
/// “date time”
/// “artist”
/// “host computer”
/// “predictor”
/// “white point”
/// “primary chromaticities”
/// “colormap”
/// “halftone hints”
/// “tile width”
/// “tile length”
/// “tile offset”
/// “tile bytecounts”
/// “inkset”
/// “ink names”
/// “number of inks”
/// “dot range”
/// “target printer”
/// “extra samples”
/// “sample format”
/// “s min sample value”
/// “s max sample value”
/// “transfer range”
/// “jpeg proc”
/// “jpeg interformat”
/// “jpeg interlength”
/// “jpeg restartinterval”
/// “jpeg losslesspredictors”
/// “jpeg pointtransforms”
/// “jpeg qtables”
/// “jpeg dctables”
/// “jpeg actables”
/// “ycbcr coefficients”
/// “ycbcr subsampling”
/// “ycbcr positioning”
/// “ref black white”
/// “icc profile”
/// “gamma”
/// “icc profile descriptor”
/// “srgb renderingintent”
/// “image title”
/// “copyright”
/// “resolution x unit”
/// “resolution y unit”
/// “resolution x lengthunit”
/// “resolution y lengthunit”
/// “print flags”
/// “print flags version”
/// “print flags crop”
/// “print flags bleed width”
/// “print flags bleed width scale”
/// “halftone lpi”
/// “halftone lpiunit”
/// “halftone degree”
/// “halftone shape”
/// “halftone misc”
/// “halftone screen”
/// “jpeg quality”
/// “grid size”
/// “thumbnail format”
/// “thumbnail width”
/// “thumbnail height”
/// “thumbnail colordepth”
/// “thumbnail planes”
/// “thumbnail rawbytes”
/// “thumbnail size”
/// “thumbnail compressedsize”
/// “color transfer function”
/// “thumbnail data”
/// “thumbnail imagewidth”
/// “thumbnail imageheight”
/// “thumbnail bitspersample”
/// “thumbnail compression”
/// “thumbnail photometricinterp”
/// “thumbnail imagedescription”
/// “thumbnail equipmake”
/// “thumbnail equipmodel”
/// “thumbnail stripoffsets”
/// “thumbnail orientation”
/// “thumbnail samplesperpixel”
/// “thumbnail rowsperstrip”
/// “thumbnail stripbytescount”
/// “thumbnail resolutionx”
/// “thumbnail resolutiony”
/// “thumbnail planarconfig”
/// “thumbnail resolutionunit”
/// “thumbnail transferfunction”
/// “thumbnail softwareused”
/// “thumbnail datetime”
/// “thumbnail artist”
/// “thumbnail whitepoint”
/// “thumbnail primarychromaticities”
/// “thumbnail ycbcrcoefficients”
/// “thumbnail ycbcrsubsampling”
/// “thumbnail ycbcrpositioning”
/// “thumbnail refblackwhite”
/// “thumbnail copyright”
/// “luminance table”
/// “chrominance table”
/// “frame delay”
/// “loop count”
/// “pixel unit”
/// “pixel perunit x”
/// “pixel perunit y”
/// “palette histogram”
/// “exposure time”
/// “f-number”
/// “exposure prog”
/// “spectral sense”
/// “iso speed”
/// “oecf”
/// “ver”
/// “dtorig”
/// “dtdigitized”
/// “compconfig”
/// “compbpp”
/// “shutter speed”
/// “aperture”
/// “brightness”
/// “exposure bias”
/// “maxaperture”
/// “subjectdist”
/// “metering mode”
/// “lightsource”
/// “flash”
/// “focallength”
/// “maker note”
/// “user comment”
/// “dtsubsec”
/// “dtorigss”
/// “dtdigss”
/// “fpxver”
/// “colorspace”
/// “pixxdim”
/// “pixydim”
/// “relatedwav”
/// “interop”
/// “flashenergy”
/// “spatialfr”
/// “focalxres”
/// “focalyres”
/// “focalresunit”
/// “subject loc”
/// “exposure index”
/// “sensing method”
/// “filesource”
/// “scenetype”
/// “cfapattern”
/// “gps ver”
/// “gps latituderef”
/// “gps latitude”
/// “gps longituderef”
/// “gps longitude”
/// “gps altituderef”
/// “gps altitude”
/// “gps gpstime”
/// “gps gpssatellites”
/// “gps gpsstatus”
/// “gps gpsmeasuremode”
/// “gps gpsdop”
/// “gps speedref”
/// “gps speed”
/// “gps trackref”
/// “gps track”
/// “gps imgdirref”
/// “gps imgdir”
/// “gps mapdatum”
/// “gps destlatref”
/// “gps destlat”
/// “gps destlongref”
/// “gps destlong”
/// “gps destbearref”
/// “gps destbear”
/// “gps destdistref”
/// “gps destdist”
/// </summary>
public object this[string index]
{
get
{
return properties[index];
}
}
//
private system.drawing.bitmap bmp;
//
private string data;
//
private translation myhash;
//
private hashtable properties;
//
internal int count
{
get
{
return this.properties.count;
}
}
//
string sp;
/// <summary>
///
/// </summary>
/// <param name=”id”></param>
/// <param name=”len”></param>
/// <param name=”type”></param>
/// <param name=”data”></param>
public void settag(int id, string data)
{
encoding ascii = encoding.ascii;
this.settag(id, data.length, 0x2, ascii.getbytes(data));
}
/// <summary>
///
/// </summary>
/// <param name=”id”></param>
/// <param name=”len”></param>
/// <param name=”type”></param>
/// <param name=”data”></param>
public void settag(int id, int len, short type, byte[] data)
{
propertyitem p = createpropertyitem(type, id, len, data);
this.bmp.setpropertyitem(p);
builddb(this.bmp.propertyitems);
}
/// <summary>
///
/// </summary>
/// <param name=”type”></param>
/// <param name=”tag”></param>
/// <param name=”len”></param>
/// <param name=”value”></param>
/// <returns></returns>
private static propertyitem createpropertyitem(short type, int tag, int len, byte[] value)
{
propertyitem item;
// loads a propertyitem from a jpeg image stored in the assembly as a resource.
assembly assembly = assembly.getexecutingassembly();
stream emptybitmapstream = assembly.getmanifestresourcestream(“exifextractor.decoy.jpg”);
system.drawing.image empty = system.drawing.image.fromstream(emptybitmapstream);
item = empty.propertyitems[0];
// copies the data to the property item.
item.type = type;
item.len = len;
item.id = tag;
item.value = new byte[value.length];
value.copyto(item.value, 0);
return item;
}
/// <summary>
///
/// </summary>
/// <param name=”bmp”></param>
/// <param name=”sp”></param>
public exifextractor(ref system.drawing.bitmap bmp, string sp)
{
properties = new hashtable();
//
this.bmp = bmp;
this.sp = sp;
//
myhash = new translation();
builddb(this.bmp.propertyitems);
}
string msp = “”;
public exifextractor(ref system.drawing.bitmap bmp, string sp, string msp)
{
properties = new hashtable();
this.sp = sp;
this.msp = msp;
this.bmp = bmp;
//
myhash = new translation();
this.builddb(bmp.propertyitems);
}
public static propertyitem[] getexifproperties(string filename)
{
filestream stream = new filestream(filename, filemode.open, fileaccess.read);
system.drawing.image image = system.drawing.image.fromstream(stream,
/* useembeddedcolormanagement = */ true,
/* validateimagedata = */ false);
return image.propertyitems;
}
public exifextractor(string file, string sp, string msp)
{
properties = new hashtable();
this.sp = sp;
this.msp = msp;
myhash = new translation();
//
this.builddb(getexifproperties(file));
}
/// <summary>
///
/// </summary>
private void builddb(system.drawing.imaging.propertyitem[] parr)
{
properties.clear();
//
data = “”;
//
encoding ascii = encoding.ascii;
//
foreach (system.drawing.imaging.propertyitem p in parr)
{
string v = “”;
string name = (string)myhash[p.id];
// tag not found. skip it
if (name == null) continue;
//
data += name + “: “;
//
//1 = byte an 8-bit unsigned integer.,
if (p.type == 0x1)
{
v = p.value[0].tostring();
}
//2 = ascii an 8-bit byte containing one 7-bit ascii code. the final byte is terminated with null.,
else if (p.type == 0x2)
{
// string
v = ascii.getstring(p.value);
}
//3 = short a 16-bit (2 -byte) unsigned integer,
else if (p.type == 0x3)
{
// orientation // lookup table
switch (p.id)
{
case 0x8827: // iso
v = “iso-” + converttoint16u(p.value).tostring();
break;
case 0xa217: // sensing method
{
switch (converttoint16u(p.value))
{
case 1: v = “not defined”; break;
case 2: v = “one-chip color area sensor”; break;
case 3: v = “two-chip color area sensor”; break;
case 4: v = “three-chip color area sensor”; break;
case 5: v = “color sequential area sensor”; break;
case 7: v = “trilinear sensor”; break;
case 8: v = “color sequential linear sensor”; break;
default: v = ” reserved”; break;
}
}
break;
case 0x8822: // aperture
switch (converttoint16u(p.value))
{
case 0: v = “not defined”; break;
case 1: v = “manual”; break;
case 2: v = “normal program”; break;
case 3: v = “aperture priority”; break;
case 4: v = “shutter priority”; break;
case 5: v = “creative program (biased toward depth of field)”; break;
case 6: v = “action program (biased toward fast shutter speed)”; break;
case 7: v = “portrait mode (for closeup photos with the background out of focus)”; break;
case 8: v = “landscape mode (for landscape photos with the background in focus)”; break;
default: v = “reserved”; break;
}
break;
case 0x9207: // metering mode
switch (converttoint16u(p.value))
{
case 0: v = “unknown”; break;
case 1: v = “average”; break;
case 2: v = “centerweightedaverage”; break;
case 3: v = “spot”; break;
case 4: v = “multispot”; break;
case 5: v = “pattern”; break;
case 6: v = “partial”; break;
case 255: v = “other”; break;
default: v = “reserved”; break;
}
break;
case 0x9208: // light source
{
switch (converttoint16u(p.value))
{
case 0: v = “unknown”; break;
case 1: v = “daylight”; break;
case 2: v = “fluorescent”; break;
case 3: v = “tungsten”; break;
case 17: v = “standard light a”; break;
case 18: v = “standard light b”; break;
case 19: v = “standard light c”; break;
case 20: v = “d55”; break;
case 21: v = “d65”; break;
case 22: v = “d75”; break;
case 255: v = “other”; break;
default: v = “reserved”; break;
}
}
break;
case 0x9209:
{
switch (converttoint16u(p.value))
{
case 0: v = “flash did not fire”; break;
case 1: v = “flash fired”; break;
case 5: v = “strobe return light not detected”; break;
case 7: v = “strobe return light detected”; break;
default: v = “reserved”; break;
}
}
break;
default:
v = converttoint16u(p.value).tostring();
break;
}
}
//4 = long a 32-bit (4 -byte) unsigned integer,
else if (p.type == 0x4)
{
// orientation // lookup table
v = converttoint32u(p.value).tostring();
}
//5 = rational two longs. the first long is the numerator and the second long expresses the//denominator.,
else if (p.type == 0x5)
{
// rational
byte[] n = new byte[p.len / 2];
byte[] d = new byte[p.len / 2];
array.copy(p.value, 0, n, 0, p.len / 2);
array.copy(p.value, p.len / 2, d, 0, p.len / 2);
uint a = converttoint32u(n);
uint b = converttoint32u(d);
rational r = new rational(a, b);
//
//convert here
//
switch (p.id)
{
case 0x9202: // aperture
v = “f/” + math.round(math.pow(math.sqrt(2), r.todouble()), 2).tostring();
break;
case 0x920a:
v = r.todouble().tostring();
break;
case 0x829a:
v = r.todouble().tostring();
break;
case 0x829d: // f-number
v = “f/” + r.todouble().tostring();
break;
default:
v = r.tostring(“/”);
break;
}
}
//7 = undefined an 8-bit byte that can take any value depending on the field definition,
else if (p.type == 0x7)
{
switch (p.id)
{
case 0xa300:
{
if (p.value[0] == 3)
{
v = “dsc”;
}
else
{
v = “reserved”;
}
break;
}
case 0xa301:
if (p.value[0] == 1)
v = “a directly photographed image”;
else
v = “not a directly photographed image”;
break;
default:
v = “-“;
break;
}
}
//9 = slong a 32-bit (4 -byte) signed integer (2s complement notation),
else if (p.type == 0x9)
{
v = converttoint32(p.value).tostring();
}
//10 = srational two slongs. the first slong is the numerator and the second slong is the
//denominator.
else if (p.type == 0xa)
{
// rational
byte[] n = new byte[p.len / 2];
byte[] d = new byte[p.len / 2];
array.copy(p.value, 0, n, 0, p.len / 2);
array.copy(p.value, p.len / 2, d, 0, p.len / 2);
int a = converttoint32(n);
int b = converttoint32(d);
rational r = new rational(a, b);
//
// convert here
//
switch (p.id)
{
case 0x9201: // shutter speed
v = “1/” + math.round(math.pow(2, r.todouble()), 2).tostring();
break;
case 0x9203:
v = math.round(r.todouble(), 4).tostring();
break;
default:
v = r.tostring(“/”);
break;
}
}
// add it to the list
if (properties[name] == null)
properties.add(name, v);
// cat it too
data += v;
data += this.sp;
}
}
/// <summary>
///
/// </summary>
/// <returns></returns>
public override string tostring()
{
return data;
}
/// <summary>
///
/// </summary>
/// <param name=”arr”></param>
/// <returns></returns>
int converttoint32(byte[] arr)
{
if (arr.length != 4)
return 0;
else
return arr[3] << 24 | arr[2] << 16 | arr[1] << 8 | arr[0];
}
/// <summary>
///
/// </summary>
/// <param name=”arr”></param>
/// <returns></returns>
int converttoint16(byte[] arr)
{
if (arr.length != 2)
return 0;
else
return arr[1] << 8 | arr[0];
}
/// <summary>
///
/// </summary>
/// <param name=”arr”></param>
/// <returns></returns>
uint converttoint32u(byte[] arr)
{
if (arr.length != 4)
return 0;
else
return convert.touint32(arr[3] << 24 | arr[2] << 16 | arr[1] << 8 | arr[0]);
}
/// <summary>
///
/// </summary>
/// <param name=”arr”></param>
/// <returns></returns>
uint converttoint16u(byte[] arr)
{
if (arr.length != 2)
return 0;
else
return convert.touint16(arr[1] << 8 | arr[0]);
}
#region ienumerable members
public ienumerator getenumerator()
{
// todo: add exifextractor.getenumerator implementation
return (new exifextractorenumerator(this.properties));
}
#endregion
}
//
// dont touch this class. its for ienumerator
//
//
class exifextractorenumerator : ienumerator
{
hashtable exiftable;
idictionaryenumerator index;
internal exifextractorenumerator(hashtable exif)
{
this.exiftable = exif;
this.reset();
index = exif.getenumerator();
}
#region ienumerator members
public void reset()
{
this.index = null;
}
public object current
{
get
{
return (new pair(this.index.key, this.index.value));
}
}
public bool movenext()
{
if (index != null && index.movenext())
return true;
else
return false;
}
#endregion
}
public class pair
{
public string first;
public string second;
public pair(object key, object value)
{
this.first = key.tostring();
this.second = value.tostring();
}
}
}
///translation.cs
using system;
using system.collections.generic;
using system.collections;
using system.text;
namespace exif
{
/// <summary>
/// summary description for translation.
/// </summary>
public class translation : hashtable
{
/// <summary>
///
/// </summary>
public translation()
{
this.add(0x8769,”exif ifd”);
this.add(0x8825,”gps ifd”);
this.add(0xfe,”new subfile type”);
this.add(0xff,”subfile type”);
this.add(0x100,”image width”);
this.add(0x101,”image height”);
this.add(0x102,”bits per sample”);
this.add(0x103,”compression”);
this.add(0x106,”photometric interp”);
this.add(0x107,”thresh holding”);
this.add(0x108,”cell width”);
this.add(0x109,”cell height”);
this.add(0x10a,”fill order”);
this.add(0x10d,”document name”);
this.add(0x10e,”image description”);
this.add(0x10f,”equip make”);
this.add(0x110,”equip model”);
this.add(0x111,”strip offsets”);
this.add(0x112,”orientation”);
this.add(0x115,”samples perpixel”);
this.add(0x116,”rows per strip”);
this.add(0x117,”strip bytes count”);
this.add(0x118,”min sample value”);
this.add(0x119,”max sample value”);
this.add(0x11a,”x resolution”);
this.add(0x11b,”y resolution”);
this.add(0x11c,”planar config”);
this.add(0x11d,”page name”);
this.add(0x11e,”x position”);
this.add(0x11f,”y position”);
this.add(0x120,”free offset”);
this.add(0x121,”free byte counts”);
this.add(0x122,”gray response unit”);
this.add(0x123,”gray response curve”);
this.add(0x124,”t4 option”);
this.add(0x125,”t6 option”);
this.add(0x128,”resolution unit”);
this.add(0x129,”page number”);
this.add(0x12d,”transfer funcition”);
this.add(0x131,”software used”);
this.add(0x132,”date time”);
this.add(0x13b,”artist”);
this.add(0x13c,”host computer”);
this.add(0x13d,”predictor”);
this.add(0x13e,”white point”);
this.add(0x13f,”primary chromaticities”);
this.add(0x140,”colormap”);
this.add(0x141,”halftone hints”);
this.add(0x142,”tile width”);
this.add(0x143,”tile length”);
this.add(0x144,”tile offset”);
this.add(0x145,”tile bytecounts”);
this.add(0x14c,”inkset”);
this.add(0x14d,”ink names”);
this.add(0x14e,”number of inks”);
this.add(0x150,”dot range”);
this.add(0x151,”target printer”);
this.add(0x152,”extra samples”);
this.add(0x153,”sample format”);
this.add(0x154,”s min sample value”);
this.add(0x155,”s max sample value”);
this.add(0x156,”transfer range”);
this.add(0x200,”jpeg proc”);
this.add(0x201,”jpeg interformat”);
this.add(0x202,”jpeg interlength”);
this.add(0x203,”jpeg restartinterval”);
this.add(0x205,”jpeg losslesspredictors”);
this.add(0x206,”jpeg pointtransforms”);
this.add(0x207,”jpeg qtables”);
this.add(0x208,”jpeg dctables”);
this.add(0x209,”jpeg actables”);
this.add(0x211,”ycbcr coefficients”);
this.add(0x212,”ycbcr subsampling”);
this.add(0x213,”ycbcr positioning”);
this.add(0x214,”ref black white”);
this.add(0x8773,”icc profile”);
this.add(0x301,”gamma”);
this.add(0x302,”icc profile descriptor”);
this.add(0x303,”srgb renderingintent”);
this.add(0x320,”image title”);
this.add(0x8298,”copyright”);
this.add(0x5001,”resolution x unit”);
this.add(0x5002,”resolution y unit”);
this.add(0x5003,”resolution x lengthunit”);
this.add(0x5004,”resolution y lengthunit”);
this.add(0x5005,”print flags”);
this.add(0x5006,”print flags version”);
this.add(0x5007,”print flags crop”);
this.add(0x5008,”print flags bleed width”);
this.add(0x5009,”print flags bleed width scale”);
this.add(0x500a,”halftone lpi”);
this.add(0x500b,”halftone lpiunit”);
this.add(0x500c,”halftone degree”);
this.add(0x500d,”halftone shape”);
this.add(0x500e,”halftone misc”);
this.add(0x500f,”halftone screen”);
this.add(0x5010,”jpeg quality”);
this.add(0x5011,”grid size”);
this.add(0x5012,”thumbnail format”);
this.add(0x5013,”thumbnail width”);
this.add(0x5014,”thumbnail height”);
this.add(0x5015,”thumbnail colordepth”);
this.add(0x5016,”thumbnail planes”);
this.add(0x5017,”thumbnail rawbytes”);
this.add(0x5018,”thumbnail size”);
this.add(0x5019,”thumbnail compressedsize”);
this.add(0x501a,”color transfer function”);
this.add(0x501b,”thumbnail data”);
this.add(0x5020,”thumbnail imagewidth”);
this.add(0x502,”thumbnail imageheight”);
this.add(0x5022,”thumbnail bitspersample”);
this.add(0x5023,”thumbnail compression”);
this.add(0x5024,”thumbnail photometricinterp”);
this.add(0x5025,”thumbnail imagedescription”);
this.add(0x5026,”thumbnail equipmake”);
this.add(0x5027,”thumbnail equipmodel”);
this.add(0x5028,”thumbnail stripoffsets”);
this.add(0x5029,”thumbnail orientation”);
this.add(0x502a,”thumbnail samplesperpixel”);
this.add(0x502b,”thumbnail rowsperstrip”);
this.add(0x502c,”thumbnail stripbytescount”);
this.add(0x502d,”thumbnail resolutionx”);
this.add(0x502e,”thumbnail resolutiony”);
this.add(0x502f,”thumbnail planarconfig”);
this.add(0x5030,”thumbnail resolutionunit”);
this.add(0x5031,”thumbnail transferfunction”);
this.add(0x5032,”thumbnail softwareused”);
this.add(0x5033,”thumbnail datetime”);
this.add(0x5034,”thumbnail artist”);
this.add(0x5035,”thumbnail whitepoint”);
this.add(0x5036,”thumbnail primarychromaticities”);
this.add(0x5037,”thumbnail ycbcrcoefficients”);
this.add(0x5038,”thumbnail ycbcrsubsampling”);
this.add(0x5039,”thumbnail ycbcrpositioning”);
this.add(0x503a,”thumbnail refblackwhite”);
this.add(0x503b,”thumbnail copyright”);
this.add(0x5090,”luminance table”);
this.add(0x5091,”chrominance table”);
this.add(0x5100,”frame delay”);
this.add(0x5101,”loop count”);
this.add(0x5110,”pixel unit”);
this.add(0x5111,”pixel perunit x”);
this.add(0x5112,”pixel perunit y”);
this.add(0x5113,”palette histogram”);
this.add(0x829a,”exposure time”);
this.add(0x829d,”f-number”);
this.add(0x8822,”exposure prog”);
this.add(0x8824,”spectral sense”);
this.add(0x8827,”iso speed”);
this.add(0x8828,”oecf”);
this.add(0x9000,”ver”);
this.add(0x9003,”dtorig”);
this.add(0x9004,”dtdigitized”);
this.add(0x9101,”compconfig”);
this.add(0x9102,”compbpp”);
this.add(0x9201,”shutter speed”);
this.add(0x9202,”aperture”);
this.add(0x9203,”brightness”);
this.add(0x9204,”exposure bias”);
this.add(0x9205,”maxaperture”);
this.add(0x9206,”subjectdist”);
this.add(0x9207,”metering mode”);
this.add(0x9208,”lightsource”);
this.add(0x9209,”flash”);
this.add(0x920a,”focallength”);
this.add(0x927c,”maker note”);
this.add(0x9286,”user comment”);
this.add(0x9290,”dtsubsec”);
this.add(0x9291,”dtorigss”);
this.add(0x9292,”dtdigss”);
this.add(0xa000,”fpxver”);
this.add(0xa001,”colorspace”);
this.add(0xa002,”pixxdim”);
this.add(0xa003,”pixydim”);
this.add(0xa004,”relatedwav”);
this.add(0xa005,”interop”);
this.add(0xa20b,”flashenergy”);
this.add(0xa20c,”spatialfr”);
this.add(0xa20e,”focalxres”);
this.add(0xa20f,”focalyres”);
this.add(0xa210,”focalresunit”);
this.add(0xa214,”subject loc”);
this.add(0xa215,”exposure index”);
this.add(0xa217,”sensing method”);
this.add(0xa300,”filesource”);
this.add(0xa301,”scenetype”);
this.add(0xa302,”cfapattern”);
this.add(0x0,”gps ver”);
this.add(0x1,”gps latituderef”);
this.add(0x2,”gps latitude”);
this.add(0x3,”gps longituderef”);
this.add(0x4,”gps longitude”);
this.add(0x5,”gps altituderef”);
this.add(0x6,”gps altitude”);
this.add(0x7,”gps gpstime”);
this.add(0x8,”gps gpssatellites”);
this.add(0x9,”gps gpsstatus”);
this.add(0xa,”gps gpsmeasuremode”);
this.add(0xb,”gps gpsdop”);
this.add(0xc,”gps speedref”);
this.add(0xd,”gps speed”);
this.add(0xe,”gps trackref”);
this.add(0xf,”gps track”);
this.add(0x10,”gps imgdirref”);
this.add(0x11,”gps imgdir”);
this.add(0x12,”gps mapdatum”);
this.add(0x13,”gps destlatref”);
this.add(0x14,”gps destlat”);
this.add(0x15,”gps destlongref”);
this.add(0x16,”gps destlong”);
this.add(0x17,”gps destbearref”);
this.add(0x18,”gps destbear”);
this.add(0x19,”gps destdistref”);
this.add(0x1a,”gps destdist”);
}
}
/// <summary>
/// private class
/// </summary>
internal class rational
{
private int n;
private int d;
public rational(int n, int d)
{
this.n = n;
this.d = d;
simplify(ref this.n, ref this.d);
}
public rational(uint n, uint d)
{
this.n = convert.toint32(n);
this.d = convert.toint32(d);
simplify(ref this.n, ref this.d);
}
public rational()
{
this.n= this.d=0;
}
public string tostring(string sp)
{
if( sp == null ) sp = “/”;
return n.tostring() + sp + d.tostring();
}
public double todouble()
{
if( d == 0 )
return 0.0;
return math.round(convert.todouble(n)/convert.todouble(d),2);
}
private void simplify( ref int a, ref int b )
{
if( a== 0 || b == 0 )
return;
int gcd = euclid(a,b);
a /= gcd;
b /= gcd;
}
private int euclid(int a, int b)
{
if(b==0)
return a;
else
return euclid(b,a%b);
}
}
}