[Serializable]
public class EXIF
{
#region -- Class level members --
// Class level members.
private Image _picture;
#endregion
#region -- Constructors --
// Constructors.
/// <summary>
/// This is default constructor of the EXIF class.
/// </summary>
public EXIF()
{
}
/// <summary>
/// This is base constructor of the EXIF class.
/// </summary>
public EXIF(string filePath)
{
_picture = Image.FromFile(filePath);
}
#endregion
#region -- Public methods --
/// <summary>
/// This method returns EXIF property values.
/// </summary>
/// <param name="exifCode">EXIF property to be returned.</param>
public string GetEXIFProperty(Definitions.exifCode exifCode)
{
// Declare local variables.
string returnValue;
try
{
// All of the EXIF properties will return strings to display in the control.
// Some of the properties require additional formatting or massaging
// of the data once it is returned. Those properties have their own
// methods.
switch (exifCode)
{
case Definitions.exifCode.ImageDescription:
returnValue = ParsedString(Definitions.exifCode.ImageDescription);
break;
case Definitions.exifCode.Make:
returnValue = ParsedString(Definitions.exifCode.Make);
break;
case Definitions.exifCode.Model:
returnValue = ParsedString(Definitions.exifCode.Model);
break;
case Definitions.exifCode.Orientation:
returnValue = Orientation();
break;
case Definitions.exifCode.XResolution:
returnValue = ParseResolution(Definitions.exifCode.XResolution);
break;
case Definitions.exifCode.YResolution:
returnValue = ParseResolution(Definitions.exifCode.YResolution);
break;
case Definitions.exifCode.ResolutionUnit:
returnValue = ResolutionUnit();
break;
case Definitions.exifCode.Software:
returnValue = ParsedString(Definitions.exifCode.Software);
break;
case Definitions.exifCode.DateTime:
returnValue = ParsedDate(Definitions.exifCode.DateTime).ToString();
break;
case Definitions.exifCode.WhitePoint:
returnValue = WhitePoint();
break;
case Definitions.exifCode.PrimaryChromaticities:
returnValue = PrimaryChromaticities();
break;
case Definitions.exifCode.YCbCrCoefficients:
returnValue = YCbCrCoefficients();
break;
case Definitions.exifCode.YCbCrPositioning:
returnValue = YCbCrPositioning();
break;
case Definitions.exifCode.ReferenceBlackWhite:
returnValue = ReferenceBlackWhite();
break;
case Definitions.exifCode.Copyright:
returnValue = ParsedString(Definitions.exifCode.Copyright);
break;
case Definitions.exifCode.ExposureTime:
returnValue = ExposureTime();
break;
case Definitions.exifCode.FNumber:
returnValue = FNumber();
break;
case Definitions.exifCode.ExposureProgram:
returnValue = ExposureProgram();
break;
case Definitions.exifCode.ISOSpeedRatings:
returnValue = UnformattedShort(Definitions.exifCode.ISOSpeedRatings);
break;
case Definitions.exifCode.ExifVersion:
returnValue = ParsedString(Definitions.exifCode.ExifVersion);
break;
case Definitions.exifCode.DateTimeOriginal:
returnValue = ParsedDate(Definitions.exifCode.DateTimeOriginal).ToString();
break;
case Definitions.exifCode.DateTimeDigitized:
returnValue = ParsedDate(Definitions.exifCode.DateTimeDigitized).ToString();
break;
case Definitions.exifCode.ComponentsConfiguration:
returnValue = ComponentsConfiguration();
break;
case Definitions.exifCode.CompressedBitsPerPixel:
returnValue = CompressedBitsPerPixel();
break;
case Definitions.exifCode.ShutterSpeedValue:
returnValue = ShutterSpeedValue();
break;
case Definitions.exifCode.ApertureValue:
returnValue = ApertureValue();
break;
case Definitions.exifCode.BrightnessValue:
returnValue = BrightnessValue();
break;
case Definitions.exifCode.ExposureBiasValue:
returnValue = ExposureBiasValue();
break;
case Definitions.exifCode.MaxApertureValue:
returnValue = MaxApertureValue();
break;
case Definitions.exifCode.SubjectDistance:
returnValue = SubjectDistance();
break;
case Definitions.exifCode.MeteringMode:
returnValue = MeteringMode();
break;
case Definitions.exifCode.LightSource:
returnValue = LightSource();
break;
case Definitions.exifCode.Flash:
returnValue = Flash();
break;
case Definitions.exifCode.FocalLength:
returnValue = FocalLength();
break;
case Definitions.exifCode.MakerNote:
returnValue = MakerNote();
break;
case Definitions.exifCode.UserComment:
returnValue = ParsedString(Definitions.exifCode.UserComment);
break;
case Definitions.exifCode.SubsecTime:
returnValue = ParsedString(Definitions.exifCode.SubsecTime);
break;
case Definitions.exifCode.SubsecTimeOriginal:
returnValue = ParsedString(Definitions.exifCode.SubsecTimeOriginal);
break;
case Definitions.exifCode.SubsecTimeDigitized:
returnValue = ParsedString(Definitions.exifCode.SubsecTimeDigitized);
break;
case Definitions.exifCode.FlashpixVersion:
returnValue = ParsedString(Definitions.exifCode.FlashpixVersion);
break;
case Definitions.exifCode.ColorSpace:
returnValue = ColorSpace();
break;
case Definitions.exifCode.RelatedSoundFile:
returnValue = ParsedString(Definitions.exifCode.RelatedSoundFile);
break;
case Definitions.exifCode.FocalPlaneXResolution:
returnValue = FocalPlaneXResolution();
break;
case Definitions.exifCode.FocalPlaneYResolution:
returnValue = FocalPlaneYResolution();
break;
case Definitions.exifCode.FocalPlaneResolutionUnit:
returnValue = ResolutionUnit();
break;
case Definitions.exifCode.ExposureIndex:
returnValue = ExposureIndex();
break;
case Definitions.exifCode.SensingMethod:
returnValue = SensingMethod();
break;
case Definitions.exifCode.FileSource:
returnValue = FileSource();
break;
case Definitions.exifCode.SceneType:
returnValue = SceneType();
break;
case Definitions.exifCode.CFAPattern:
returnValue = ParsedString(Definitions.exifCode.CFAPattern);
break;
case Definitions.exifCode.InteroperabilityIndex:
returnValue = ParsedString(Definitions.exifCode.InteroperabilityIndex);
break;
case Definitions.exifCode.ImageWidth:
returnValue = UnformattedShort(Definitions.exifCode.ImageWidth);
break;
case Definitions.exifCode.ImageLength:
returnValue = UnformattedShort(Definitions.exifCode.ImageLength); ;
break;
case Definitions.exifCode.BitsPerSample:
returnValue = BitsPerSample();
break;
case Definitions.exifCode.Compression:
returnValue = Compression();
break;
case Definitions.exifCode.PhotometricInterpretation:
returnValue = PhotometricInterpretation();
break;
case Definitions.exifCode.StripOffsets:
returnValue = StripOffsets();
break;
case Definitions.exifCode.SamplesPerPixel:
returnValue = UnformattedShort(Definitions.exifCode.SamplesPerPixel);
break;
case Definitions.exifCode.RowsPerStrip:
returnValue = UnformattedShort(Definitions.exifCode.RowsPerStrip);
break;
case Definitions.exifCode.StripByteCounts:
returnValue = StripByteCounts();
break;
case Definitions.exifCode.PlanarConfiguration:
returnValue = PlanarConfiguration();
break;
case Definitions.exifCode.YCbCrSubSampling:
returnValue = YCbCrSubSampling();
break;
case Definitions.exifCode.ImageUniqueID:
returnValue = ParsedString(Definitions.exifCode.ImageUniqueID);
break;
case Definitions.exifCode.JPEGInterchangeFormatLength:
returnValue = UnformattedShort(Definitions.exifCode.JPEGInterchangeFormatLength);
break;
case Definitions.exifCode.TransferFunction:
returnValue = "Not implemented.";
break;
case Definitions.exifCode.PixelXDimension:
returnValue = UnformattedShort(Definitions.exifCode.PixelXDimension);
break;
case Definitions.exifCode.PixelYDimension:
returnValue = UnformattedShort(Definitions.exifCode.PixelYDimension);
break;
case Definitions.exifCode.SpectralSensitivity:
returnValue = ParsedString(Definitions.exifCode.SpectralSensitivity);
break;
case Definitions.exifCode.OECF:
returnValue = ParsedString(Definitions.exifCode.OECF);
break;
case Definitions.exifCode.CustomRendered:
returnValue = CustomRendered();
break;
case Definitions.exifCode.ExposureMode:
returnValue = ExposureMode();
break;
case Definitions.exifCode.WhiteBalance:
returnValue = WhiteBalance();
break;
case Definitions.exifCode.DigitalZoomRatio:
returnValue = DigitalZoomRatio();
break;
case Definitions.exifCode.FocalLengthIn35mmFilm:
returnValue = FocalLengthIn35mmFilm();
break;
case Definitions.exifCode.SceneCaptureType:
returnValue = SceneCaptureType();
break;
case Definitions.exifCode.GainControl:
returnValue = GainControl();
break;
case Definitions.exifCode.Contrast:
returnValue = Contrast();
break;
case Definitions.exifCode.Saturation:
returnValue = Saturation();
break;
case Definitions.exifCode.Sharpness:
returnValue = Sharpness();
break;
case Definitions.exifCode.DeviceSettingDescription:
returnValue = ParsedString(Definitions.exifCode.DeviceSettingDescription);
break;
case Definitions.exifCode.SubjectDistanceRange:
returnValue = SubjectDistanceRange();
break;
default:
returnValue = "EXIF property not found.";
break;
}
return returnValue;
}
catch
{
return "N/A";
}
}
#endregion
#region -- EXIF Methods --
/// <summary>
/// This method returns the bits per sample EXIF property.
/// </summary>
private string BitsPerSample()
{
//Declare local variables.
string returnValue = "EXIF property not found.";
byte[] data = GetPropertyValue(Definitions.exifCode.BitsPerSample);
//Translate the EXIF code into a readable value.
if (!data.Equals(null))
{
returnValue = data[0].ToString() + " " + data[1].ToString() + " " + data[2].ToString();
}
return returnValue;
}
/// <summary>
/// This method returns the compression EXIF property.
/// </summary>
private string Compression()
{
//Declare local variables.
string returnValue = "EXIF property not found.";
byte[] data = GetPropertyValue(Definitions.exifCode.Compression);
//Translate the EXIF code into a readable value.
if (!data.Equals(null))
{
switch (data[0])
{
case 1:
returnValue = "uncompressed";
break;
case 6:
returnValue = "JPEG compression (thumbnails only)";
break;
default:
returnValue = "reserved";
break;
}
}
return returnValue;
}
/// <summary>
/// This method returns the photometric interpretation EXIF property.
/// </summary>
private string PhotometricInterpretation()
{
//Declare local variables.
string returnValue = "EXIF property not found.";
byte[] data = GetPropertyValue(Definitions.exifCode.PhotometricInterpretation);
//Translate the EXIF code into a readable value.
if (data != null)
{
switch (data[0])
{
case 2:
returnValue = "RBG";
break;
case 6:
returnValue = "YCbCr";
break;
default:
returnValue = "reserved";
break;
}
}
return returnValue;
}
/// <summary>
/// This method returns the strip offsets EXIF property.
/// </summary>
private string StripOffsets()
{
return "Not implemented.";
}
/// <summary>
/// This method returns the strip byte counts EXIF property.
/// </summary>
private string StripByteCounts()
{
return "Not implemented.";
}
/// <summary>
/// This method returns the planar configuration EXIF property.
/// </summary>
private string PlanarConfiguration()
{
//Declare local variables.
string returnValue = "EXIF property not found.";
byte[] data = GetPropertyValue(Definitions.exifCode.PlanarConfiguration);
//Translate the EXIF code into a readable value.
if (data != null)
{
switch (data[0])
{
case 1:
returnValue = "chunky format";
break;
case 2:
returnValue = "planar format";
break;
default:
returnValue = "reserved";
break;
}
}
return returnValue;
}
/// <summary>
/// This method returns the YCbCr subsampling EXIF property.
/// </summary>
private string YCbCrSubSampling()
{
//Declare local variables.
string returnValue = "EXIF property not found.";
byte[] data = GetPropertyValue(Definitions.exifCode.YCbCrSubSampling);
//Translate the EXIF code into a readable value.
if (data != null)
{
switch (data[0])
{
case 2:
if (data[1] == 1)
{
returnValue = "YCbCr4:2:2";
}
else
{
returnValue = "YCbCr4:2:0";
}
break;
default:
returnValue = "reserved";
break;
}
}
return returnValue;
}
/// <summary>
/// This method returns the orientation EXIF property.
/// </summary>
private string Orientation()
{
//Declare local variables.
string returnValue = "EXIF property not found.";
byte[] data = GetPropertyValue(Definitions.exifCode.Orientation);
//Translate the EXIF code into a readable value.
if (data.Length > 0)
{
switch (data[0])
{
case 1:
returnValue = "The 0th row is at the visual top of the image, and the 0th column is the visual left-hand side.";
break;
case 2:
returnValue = "The 0th row is at the visual top of the image, and the 0th column is the visual right-hand side.";
break;
case 3:
returnValue = "The 0th row is at the visual bottom of the image, and the 0th column is the visual right-hand side.";
break;
case 4:
returnValue = "The 0th row is at the visual bottom of the image, and the 0th column is the visual left-hand side.";
break;
case 5:
returnValue = "The 0th row is at the visual left-hand side of the image, and the 0th column is the visual top.";
break;
case 6:
returnValue = "The 0th row is at the visual right-hand side of the image, and the 0th column is the visual top.";
break;
case 7:
returnValue = "The 0th row is at the visual right-hand side of the image, and the 0th column is the visual bottom.";
break;
case 8:
returnValue = "The 0th row is at the visual left-hand side of the image, and the 0th column is the visual bottom.";
break;
default:
returnValue = "Other";
break;
}
}
return returnValue;
}
/// <summary>
/// This method returns the resolution unit EXIF property.
/// </summary>
private string ResolutionUnit()
{
//Declare local variables.
string returnValue = "EXIF property not found.";
byte[] resUnit = GetPropertyValue(Definitions.exifCode.ResolutionUnit);
//Translate the EXIF code into a readable value.
if (resUnit != null)
{
switch (resUnit[0])
{
case 2:
returnValue = "inches";
break;
case 3:
returnValue = "centimeters";
break;
default:
returnValue = "reserved";
break;
}
}
return returnValue;
}
/// <summary>
/// This method returns the white point EXIF property.
/// </summary>
private string WhitePoint()
{
string returnValue = "EXIF property not found.";
EXIFRational[] data = ParsedRationalArray(Definitions.exifCode.WhitePoint);
if (data.Length > 0)
{
returnValue = data[0].Denominator.ToString() + ", " + data[1].Denominator.ToString();
}
return returnValue;
}
/// <summary>
/// This method returns the primary chromaticities EXIF property.
/// </summary>
private string PrimaryChromaticities()
{
string returnValue = "EXIF property not found.";
EXIFRational[] data = ParsedRationalArray(Definitions.exifCode.PrimaryChromaticities);
if (data.Length > 0)
{
returnValue = data[0].Denominator.ToString() + ", "
+ data[1].Denominator.ToString() + ", "
+ data[2].Denominator.ToString() + ", "
+ data[3].Denominator.ToString() + ", "
+ data[4].Denominator.ToString() + ", "
+ data[5].Denominator.ToString();
}
return returnValue;
}
/// <summary>
/// This method returns the YCbCr coefficients EXIF property.
/// </summary>
private string YCbCrCoefficients()
{
string returnValue = "EXIF property not found.";
EXIFRational[] data = ParsedRationalArray(Definitions.exifCode.YCbCrCoefficients);
if (data.Length > 0)
{
returnValue = data[0].Denominator.ToString() + ", " + data[1].Denominator.ToString() + ", " + data[2].Denominator.ToString();
}
return returnValue;
}
/// <summary>
/// This method returns the YCbCr positioning EXIF property.
/// </summary>
private string YCbCrPositioning()
{
//Declare local variables.
string returnValue = "";
byte[] data = GetPropertyValue(Definitions.exifCode.YCbCrPositioning);
//Translate the EXIF code into a readable value.
if (data.Length > 0)
{
switch (data[0])
{
case 1:
returnValue = "centered";
break;
case 2:
returnValue = "co-sited";
break;
default:
returnValue = "reserved";
break;
}
}
else
{
returnValue = "EXIF property not found.";
}
return returnValue;
}
/// <summary>
/// This method returns the reference black white EXIF property.
/// </summary>
private string ReferenceBlackWhite()
{
string returnValue = "EXIF property not found.";
EXIFRational[] data = ParsedRationalArray(Definitions.exifCode.ReferenceBlackWhite);
if (data.Length > 0)
{
returnValue = "[" + data[0].Denominator.ToString() + ", "
+ data[1].Denominator.ToString() + ", "
+ data[2].Denominator.ToString() + ", "
+ data[3].Denominator.ToString() + ", "
+ data[4].Denominator.ToString() + ", "
+ data[5].Denominator.ToString() + "]";
}
return returnValue;
}
/// <summary>
/// This method returns the exposure time EXIF property.
/// </summary>
private string ExposureTime()
{
//Declare local variables.
string returnValue = "EXIF property not found.";
EXIFRational exposureTime = ParsedRational(Definitions.exifCode.ExposureTime);
//Translate the EXIF code into a readable value.
if (!exposureTime.Equals(null))
{
if (exposureTime.Numerator == 0 && exposureTime.Denominator == 0)
{
returnValue = "N/A";
}
else
{
returnValue = string.Format("{0}/{1} s", exposureTime.Numerator, exposureTime.Denominator);
}
}
else
{
returnValue = "N/A";
}
return returnValue;
}
/// <summary>
/// This method returns the FNumber EXIF property.
/// </summary>
private string FNumber()
{
//Declare local variables.
string returnValue = "EXIF property not found.";
EXIFRational fNumber = ParsedRational(Definitions.exifCode.FNumber);
//Translate the EXIF code into a readable value.
if (!fNumber.Equals(null))
{
returnValue = string.Format("f{0}", (float)(fNumber.Numerator / fNumber.Denominator));
}
return returnValue;
}
/// <summary>
/// This method returns the exposure program EXIF property.
/// </summary>
private string ExposureProgram()
{
//Declare local variables.
string returnValue = "EXIF property not found.";
byte[] data = GetPropertyValue(Definitions.exifCode.ExposureProgram);
//Translate the EXIF code into a readable value.
if (data.Length > 0)
{
switch (data[0])
{
case 0:
returnValue = "Not defined";
break;
case 1:
returnValue = "Manual";
break;
case 2:
returnValue = "Normal program";
break;
case 3:
returnValue = "Aperture priority";
break;
case 4:
returnValue = "Shutter priority";
break;
case 5:
returnValue = "Creative program (biased toward depth of field)";
break;
case 6:
returnValue = "Action program (biased toward fast shutter speed)";
break;
case 7:
returnValue = "Portrait mode (for closeup photos with the background out of focus)";
break;
case 8:
returnValue = "Landscape mode (for landscape photos with the background in focus)";
break;
default:
returnValue = "Reserved";
break;
}
}
return returnValue;
}
/// <summary>
/// This method returns the components configuration EXIF property.
/// </summary>
private string ComponentsConfiguration()
{
//Declare local variables.
string returnValue = "EXIF property not found.";
byte[] data = GetPropertyValue(Definitions.exifCode.ComponentsConfiguration);
switch (data[0])
{
case 1:
returnValue = "YCbCr";
break;
case 4:
returnValue = "RGB";
break;
default:
returnValue = "Reserved";
break;
}
return returnValue;
}
/// <summary>
/// This method returns the compressed bits per pixel EXIF property.
/// </summary>
// This method needs to fixed to return the correct value.
private string CompressedBitsPerPixel()
{
//Declare local variables.
string returnValue = "EXIF property not found.";
EXIFRational cbpp = ParsedRational(Definitions.exifCode.CompressedBitsPerPixel);
//Translate the EXIF code into a readable value.
if (!cbpp.Equals(null))
{
returnValue = string.Format("{0}/{1}", cbpp.Numerator, cbpp.Denominator);
}
return returnValue;
}
/// <summary>
/// This method returns the aperture value EXIF property.
/// </summary>
private string ApertureValue()
{
//Declare local variables.
string returnValue = "EXIF property not found.";
EXIFRational fNumber = ParsedRational(Definitions.exifCode.FNumber);
//Translate the EXIF code into a readable value.
if (!fNumber.Equals(null))
{
double av = Math.Round(2 * Math.Log(((fNumber.Numerator / fNumber.Denominator)), 2.00));
returnValue = string.Format("f{0}", (double)av);
}
return returnValue;
}
/// <summary>
/// This method returns the shutter speed value EXIF property.
/// </summary>
private string ShutterSpeedValue()
{
//Declare local variables.
string returnValue = "EXIF property not found.";
returnValue = ExposureTime();
return returnValue;
}
/// <summary>
/// This method returns the subject distance EXIF property.
/// </summary>
private string SubjectDistance()
{
//Declare local variables.
string returnValue = "EXIF property not found.";
EXIFRational sd = ParsedRational(Definitions.exifCode.SubjectDistance);
//Translate the EXIF code into a readable value.
if (!sd.Equals(null))
{
returnValue = string.Format("{0}", sd.Numerator);
}
return returnValue;
}
/// <summary>
/// This method returns the metering mode EXIF property.
/// </summary>
private string MeteringMode()
{
//Declare local variables.
string returnValue = "EXIF property not found.";
byte[] data = GetPropertyValue(Definitions.exifCode.MeteringMode);
//Translate the EXIF code into a readable value.
if (data.Length > 0)
{
switch (data[0])
{
case 0:
returnValue = "Unknown";
break;
case 1:
returnValue = "Average";
break;
case 2:
returnValue = "CenterWeightedAverage";
break;
case 3:
returnValue = "Spot";
break;
case 4:
returnValue = "MultiSpot";
break;
case 5:
returnValue = "Pattern";
break;
case 6:
returnValue = "Partial";
break;
case 255:
returnValue = "Other";
break;
default:
returnValue = "Reserved";
break;
}
}
return returnValue;
}
/// <summary>
/// This method returns the light source EXIF property.
/// </summary>
private string LightSource()
{
//Declare local variables.
string returnValue = "EXIF property not found.";
byte[] data = GetPropertyValue(Definitions.exifCode.LightSource);
//Translate the EXIF code into a readable value.
if (data.Length > 0)
{
switch (data[0])
{
case 1:
returnValue = "Daylight";
break;
case 2:
returnValue = "Fluorescent";
break;
case 3:
returnValue = "Tungsten (incandescent light)";
break;
case 4:
returnValue = "Flash";
break;
case 9:
returnValue = "Fine weather";
break;
case 10:
returnValue = "Cloudy weather";
break;
case 11:
returnValue = "Shade";
break;
case 12:
returnValue = "Daylight fluorescent (D 5700 - 7100K)";
break;
case 13:
returnValue = "Day white fluorescent (N 4600 - 5400K)";
break;
case 14:
returnValue = "Cool white fluorescent (W 3900 - 4500K)";
break;
case 15:
returnValue = "White fluorescent (WW 3200 - 3700K)";
break;
case 17:
returnValue = "Standard light A";
break;
case 18:
returnValue = "Standard light B";
break;
case 19:
returnValue = "Standard light C";
break;
case 20:
returnValue = "D55";
break;
case 21:
returnValue = "D65";
break;
case 22:
returnValue = "D75.";
break;
case 23:
returnValue = "D50";
break;
case 24:
returnValue = "ISO studio tungsten";
break;
case 255:
returnValue = "other light source";
break;
default:
returnValue = "Reserved";
break;
}
}
return returnValue;
}
/// <summary>
/// This method returns the flash EXIF property.
/// </summary>
private string Flash()
{
//Declare local variables.
string returnValue = "EXIF property not found.";
byte[] data = GetPropertyValue(Definitions.exifCode.Flash);
//Translate the EXIF code into a readable value.
if (data.Length > 0)
{
switch (data[0])
{
case 0:
returnValue = "Flash did not fire.";
break;
case 1:
returnValue = "Flash fired.";
break;
case 5:
returnValue = "Strobe return light not detected.";
break;
case 7:
returnValue = "Strobe return light detected.";
break;
case 9:
returnValue = "Flash fired, compulsory flash mode.";
break;
case 13:
returnValue = "Flash fired, compulsory flash mode, return light not detected.";
break;
case 15:
returnValue = "Flash fired, compulsory flash mode, return light detected.";
break;
case 16:
returnValue = "Flash did not fire, compulsory flash mode.";
break;
case 24:
returnValue = "Flash did not fire, auto mode.";
break;
case 25:
returnValue = "Flash fired, auto mode.";
break;
case 29:
returnValue = "Flash fired, auto mode, return light not detected.";
break;
case 31:
returnValue = "Flash fired, auto mode, return light detected.";
break;
case 32:
returnValue = "No flash function.";
break;
case 65:
returnValue = "Flash fired, red-eye reduction mode.";
break;
case 69:
returnValue = "Flash fired, red-eye reduction mode, return light not detected.";
break;
case 71:
returnValue = "Flash fired, red-eye reduction mode, return light detected.";
break;
case 73:
returnValue = "Flash fired, compulsory flash mode, red-eye reduction mode.";
break;
case 77:
returnValue = "Flash fired, compulsory flash mode, red-eye reduction mode, return light not detected.";
break;
case 79:
returnValue = "Flash fired, compulsory flash mode, red-eye reduction mode, return light detected.";
break;
case 89:
returnValue = "Flash fired, auto mode, red-eye reduction mode.";
break;
case 93:
returnValue = "Flash fired, auto mode, return light not detected, red-eye reduction mode.";
break;
case 95:
returnValue = "Flash fired, auto mode, return light detected, red-eye reduction mode.";
break;
default:
returnValue = "Not defined, reserved.";
break;
}
}
return returnValue;
}
/// <summary>
/// This method returns the focal length EXIF property.
/// </summary>
private string FocalLength()
{
//Declare local variables.
string returnValue = "EXIF property not found.";
EXIFRational focalLength = ParsedRational(Definitions.exifCode.FocalLength);
//Translate the EXIF code into a readable value.
if (!focalLength.Equals(null))
{
if (focalLength.Numerator == 0 && focalLength.Denominator == 0)
{
returnValue = "N/A";
}
else
{
returnValue = string.Format("{0:N0} mm", focalLength.Numerator * 1.0 / focalLength.Denominator);
}
}
return returnValue;
}
/// <summary>
/// This method returns the maker note EXIF property.
/// </summary>
private string MakerNote()
{
return "Not implemented.";
}
/// <summary>
/// This method returns the color space EXIF property.
/// </summary>
private string ColorSpace()
{
//Declare local variables.
string returnValue = "EXIF property not found.";
byte[] data = GetPropertyValue(Definitions.exifCode.ColorSpace);
//Translate the EXIF code into a readable value.
if (data.Length > 0)
{
switch (data[0])
{
case 1:
returnValue = "sRGB";
break;
case 255:
returnValue = "Uncalibrated";
break;
default:
returnValue = "Reserved";
break;
}
}
return returnValue;
}
/// <summary>
/// This method returns the focal plane x resolution EXIF property.
/// </summary>
private string FocalPlaneXResolution()
{
//Declare local variables.
string returnValue = "EXIF property not found.";
EXIFRational focalPlaneXRes = ParsedRational(Definitions.exifCode.FocalPlaneXResolution);
//Translate the EXIF code into a readable value.
if (!focalPlaneXRes.Equals(null))
{
returnValue = string.Format("{0:N0} mm", (focalPlaneXRes.Numerator * 1.0 / focalPlaneXRes.Denominator));
}
return returnValue;
}
/// <summary>
/// This method returns the focal plane y resolution EXIF property.
/// </summary>
private string FocalPlaneYResolution()
{
//Declare local variables.
string returnValue = "EXIF property not found.";
EXIFRational focalPlaneYRes = ParsedRational(Definitions.exifCode.FocalPlaneYResolution);
//Translate the EXIF code into a readable value.
if (!focalPlaneYRes.Equals(null))
{
returnValue = string.Format("{0:N0} mm", focalPlaneYRes.Numerator * 1.0 / focalPlaneYRes.Denominator);
}
return returnValue;
}
/// <summary>
/// This method returns the exposure index EXIF property.
/// </summary>
private string ExposureIndex()
{
//Declare local variables.
string returnValue = "EXIF property not found.";
EXIFRational expIndex = ParsedRational(Definitions.exifCode.ExposureIndex);
//Translate the EXIF code into a readable value.
if (!expIndex.Equals(null))
{
returnValue = string.Format("{0:N0} mm", expIndex.Numerator * 1.0 / expIndex.Denominator);
}
return returnValue;
}
/// <summary>
/// This method returns the sensing method EXIF property.
/// </summary>
private string SensingMethod()
{
// Declare local variables.
// Get the value for this EXIF property.
byte[] data = GetPropertyValue(Definitions.exifCode.SensingMethod);
string returnValue = "EXIF property not found.";
if (data.Length > 0)
{
switch (data[0])
{
case 1:
returnValue = "Not defined.";
break;
case 2:
returnValue = "One-chip color area sensor.";
break;
case 3:
returnValue = "Two-chip color area sensor.";
break;
case 4:
returnValue = "Three-chip color area sensor.";
break;
case 5:
returnValue = "Color sequential area sensor.";
break;
case 7:
returnValue = "Trilinear sensor.";
break;
case 8:
returnValue = "Color sequential linear sensor";
break;
default:
returnValue = "Reserved.";
break;
}
}
return returnValue;
}
/// <summary>
/// This method returns the file source EXIF property.
/// </summary>
private string FileSource()
{
// Declare local variables.
// Get the value for this EXIF property.
byte[] data = GetPropertyValue(Definitions.exifCode.FileSource);
string returnValue = "EXIF property not found.";
if (data.Length > 0)
{
switch (data[0])
{
case 3:
returnValue = "DSC";
break;
default:
returnValue = "Reserved";
break;
}
}
return returnValue;
}
/// <summary>
/// This method returns the scene type EXIF property.
/// </summary>
private string SceneType()
{
// Declare local variables.
// Get the value for this EXIF property.
byte[] data = GetPropertyValue(Definitions.exifCode.FileSource);
string returnValue = "EXIF property not found.";
if (data.Length > 0)
{
switch (data[0])
{
case 1:
returnValue = "A directly photographed image.";
break;
default:
returnValue = "Reserved.";
break;
}
}
return returnValue;
}
/// <summary>
/// This method returns the custom rendered EXIF property.
/// </summary>
private string CustomRendered()
{
// Declare local variables.
// Get the value for this EXIF property.
byte[] data = GetPropertyValue(Definitions.exifCode.CustomRendered);
string returnValue = "EXIF property not found.";
if (data.Length > 0)
{
switch (data[0])
{
case 0:
returnValue = "Normal process";
break;
case 1:
returnValue = "Custom process";
break;
default:
returnValue = "Reserved";
break;
}
}
return returnValue;
}
/// <summary>
/// This method returns the exposure mode EXIF property.
/// </summary>
private string ExposureMode()
{
// Declare local variables.
// Get the value for this EXIF property.
byte[] data = GetPropertyValue(Definitions.exifCode.ExposureMode);
string returnValue = "EXIF property not found.";
if (data.Length > 0)
{
switch (data[0])
{
case 0:
returnValue = "Auto exposure";
break;
case 1:
returnValue = "Manual exposure";
break;
case 2:
returnValue = "Auto bracket";
break;
default:
returnValue = "Reserved";
break;
}
}
return returnValue;
}
/// <summary>
/// This method returns the white balance EXIF property.
/// </summary>
private string WhiteBalance()
{
// Declare local variables.
// Get the value for this EXIF property.
byte[] data = GetPropertyValue(Definitions.exifCode.WhiteBalance);
string returnValue = "EXIF property not found.";
if (data.Length > 0)
{
switch (data[0])
{
case 0:
returnValue = "Auto white balance";
break;
case 1:
returnValue = "Manual white balance";
break;
default:
returnValue = "Reserved";
break;
}
}
return returnValue;
}
/// <summary>
/// This method returns the focal length in 35mm film EXIF property.
/// </summary>
private string FocalLengthIn35mmFilm()
{
// Declare local variables.
// Get the value for this EXIF property.
byte[] data = GetPropertyValue(Definitions.exifCode.FocalLengthIn35mmFilm);
string returnValue = "EXIF property not found.";
if (data.Length > 0)
{
if (data[0] == 0)
{
returnValue = "Unknown";
}
else if (data[0].ToString().Trim() == "NaN")
{
returnValue = "N/A";
}
else
{
returnValue = data[0].ToString() + "mm";
}
}
return returnValue;
}
/// <summary>
/// This method returns the scene capture type EXIF property.
/// </summary>
private string SceneCaptureType()
{
// Declare local variables.
// Get the value for this EXIF property.
byte[] data = GetPropertyValue(Definitions.exifCode.SceneCaptureType);
string returnValue = "EXIF property not found.";
if (data.Length > 0)
{
switch (data[0])
{
case 0:
returnValue = "Standard";
break;
case 1:
returnValue = "Landscape";
break;
case 2:
returnValue = "Portrait";
break;
case 3:
returnValue = "Night scene";
break;
default:
returnValue = "Reserved";
break;
}
}
return returnValue;
}
/// <summary>
/// This method returns the gain control EXIF property.
/// </summary>
private string GainControl()
{
// Declare local variables.
// Get the value for this EXIF property.
byte[] data = GetPropertyValue(Definitions.exifCode.GainControl);
string returnValue = "EXIF property not found.";
if (data.Length > 0)
{
switch (data[0])
{
case 0:
returnValue = "None";
break;
case 1:
returnValue = "Low gain up";
break;
case 2:
returnValue = "High gain up";
break;
case 3:
returnValue = "Low gain down";
break;
case 4:
returnValue = "High gain down";
break;
default:
returnValue = "Reserved";
break;
}
}
return returnValue;
}
/// <summary>
/// This method returns the contrast EXIF property.
/// </summary>
private string Contrast()
{
// Declare local variables.
// Get the value for this EXIF property.
byte[] data = GetPropertyValue(Definitions.exifCode.Contrast);
string returnValue = "EXIF property not found.";
if (data.Length > 0)
{
switch (data[0])
{
case 0:
returnValue = "Normal";
break;
case 1:
returnValue = "Soft";
break;
case 2:
returnValue = "Hard";
break;
default:
returnValue = "Reserved";
break;
}
}
return returnValue;
}
/// <summary>
/// This method returns the saturation EXIF property.
/// </summary>
private string Saturation()
{
// Declare local variables.
// Get the value for this EXIF property.
byte[] data = GetPropertyValue(Definitions.exifCode.Saturation);
string returnValue = "EXIF property not found.";
if (data.Length > 0)
{
switch (data[0])
{
case 0:
returnValue = "Normal";
break;
case 1:
returnValue = "Low saturation";
break;
case 2:
returnValue = "High saturation";
break;
default:
returnValue = "Reserved";
break;
}
}
return returnValue;
}
/// <summary>
/// This method returns the sharpness EXIF property.
/// </summary>
private string Sharpness()
{
// Declare local variables.
// Get the value for this EXIF property.
byte[] data = GetPropertyValue(Definitions.exifCode.Sharpness);
string returnValue = "EXIF property not found.";
if (data.Length > 0)
{
switch (data[0])
{
case 0:
returnValue = "Normal";
break;
case 1:
returnValue = "Soft";
break;
case 2:
returnValue = "Hard";
break;
default:
returnValue = "Reserved";
break;
}
}
return returnValue;
}
/// <summary>
/// This method returns the subject distance range EXIF property.
/// </summary>
private string SubjectDistanceRange()
{
// Declare local variables.
// Get the value for this EXIF property.
byte[] data = GetPropertyValue(Definitions.exifCode.SubjectDistanceRange);
string returnValue = "EXIF property not found.";
if (data.Length > 0)
{
switch (data[0])
{
case 0:
returnValue = "Unknown";
break;
case 1:
returnValue = "Macro";
break;
case 2:
returnValue = "Close view";
break;
case 3:
returnValue = "Distant view";
break;
default:
returnValue = "Reserved";
break;
}
}
return returnValue;
}
/// <summary>
/// This method returns the subject location EXIF property.
/// </summary>
private string SubjectLocation()
{
// Declare local variables.
// Get the value for this EXIF property.
byte[] data = GetPropertyValue(Definitions.exifCode.SubjectLocation);
string returnValue = "EXIF property not found.";
if (data.Length > 0)
{
returnValue = "(" + data[0].ToString() + ", " + data[1].ToString() + ")";
}
return returnValue;
}
/// <summary>
/// This method returns the digital zoom ratio EXIF property.
/// </summary>
private string DigitalZoomRatio()
{
//Declare local variables.
string returnValue = "EXIF property not found.";
EXIFRational dzr = ParsedRational(Definitions.exifCode.DigitalZoomRatio);
//Translate the EXIF code into a readable value.
if (!dzr.Equals(null))
{
returnValue = dzr.Numerator.ToString() + ":" + dzr.Denominator.ToString();
}
return returnValue;
}
/// <summary>
/// This method returns the brightness value EXIF property.
/// </summary>
private string BrightnessValue()
{
//Declare local variables.
string returnValue = "EXIF property not found.";
EXIFRational data = ParsedRational(Definitions.exifCode.DigitalZoomRatio);
//Translate the EXIF code into a readable value.
if (!data.Equals(null))
{
if ((long)data.Numerator >= Int32.MaxValue)
{
returnValue = "Unknown";
}
else
{
returnValue = Math.Log(data.Numerator / data.Denominator, 2.0).ToString();
}
}
return returnValue;
}
/// <summary>
/// This method returns the max aperture value EXIF property.
/// </summary>
private string MaxApertureValue()
{
//Declare local variables.
string returnValue = "EXIF property not found.";
EXIFRational data = ParsedRational(Definitions.exifCode.MaxApertureValue);
//Translate the EXIF code into a readable value.
if (!data.Equals(null))
{
returnValue = string.Format("f{0}", (double)(data.Numerator / data.Denominator));
}
return returnValue;
}
/// <summary>
/// This method returns the exposure bias value EXIF property.
/// </summary>
private string ExposureBiasValue()
{
//Declare local variables.
string returnValue = "EXIF property not found.";
EXIFRational data = ParsedRational(Definitions.exifCode.ExposureBiasValue);
//Translate the EXIF code into a readable value.
if (!data.Equals(null))
{
returnValue = string.Format("f{0}", (double)(data.Numerator / data.Denominator));
}
return returnValue;
}
#endregion
#region -- Private helper functions --
// Private helper functions.
/// <summary>
/// This method retrieves the data from the propery items collection.
/// </summary>
private byte[] GetPropertyValue(Definitions.exifCode exifCode)
{
return _picture.GetPropertyItem((int)exifCode).Value;
}
/// <summary>
/// This method returns string EXIF data.
/// </summary>
private string ParsedString(Definitions.exifCode exifCode)
{
// Declare local variables.
// Retrieve the data for this EXIF property.
byte[] data = GetPropertyValue(exifCode);
// Holds the return value.
string parsed = "";
// If there's data, go ahead and parse it.
if (data.Length > 1)
{
// Allocate some memory.
IntPtr h = Marshal.AllocHGlobal(data.Length);
int i = 0;
foreach (byte b in data)
{
Marshal.WriteByte(h, i, b);
i++;
}
parsed = Marshal.PtrToStringAnsi(h);
Marshal.FreeHGlobal(h);
}
return parsed;
}
/// <summary>
/// This method returns rational EXIF data.
/// </summary>
private EXIFRational ParsedRational(Definitions.exifCode exifCode)
{
// Declare local variables.
// Retrieve the data for this EXIF property.
byte[] data = GetPropertyValue(exifCode);
// Parse the data.
EXIFRational parsed = new EXIFRational(data);
return parsed;
}
/// <summary>
/// This method returns an array of rational EXIF data.
/// </summary>
private EXIFRational[] ParsedRationalArray(Definitions.exifCode exifCode)
{
// Declare local variables.
// Retrieve the data for this EXIF property.
byte[] data = GetPropertyValue(exifCode);
// Holds the return value.
EXIFRational[] parsed = null;
int arraySize = (data.Length / 8);
if (arraySize > 0)
{
parsed = new EXIFRational[arraySize];
for (int i = 0; i < arraySize; i++)
{
parsed[i] = new EXIFRational(data, i * 8);
}
}
return parsed;
}
/// <summary>
/// This method returns date/time EXIF data.
/// </summary>
private DateTime ParsedDate(Definitions.exifCode exifCode)
{
// Declare local variables.
// Create a new date object.
DateTime ret = new DateTime(1900, 1, 1, 0, 0, 0);
// Parse the data.
string date = ParsedString(exifCode);
// Format the data.
if (date.Length >= 19)
{