private void ExifGpsView_Format(object sender, ConvertEventArgs e)
        {
            GpsCoordinate c = e.Value as GpsCoordinate;

            if (c != null)
            {
                e.Value = c.ToString();
            }
            else
            {
                e.Value = "";
            }
        }
Beispiel #2
0
        /// <summary>
        ///
        /// </summary>
        /// <returns></returns>
        /// <remarks>
        /// References:
        /// http://www.media.mit.edu/pia/Research/deepview/exif.html
        /// http://en.wikipedia.org/wiki/APEX_system
        /// http://en.wikipedia.org/wiki/Exposure_value
        /// </remarks>
        protected string FormatValue()
        {
            object rawValue = this.Value;

            switch (this.Tag)
            {
            case ExifTag.ISOSpeed:
            {
                if (rawValue is Array)
                {
                    Array array = (Array)rawValue;
                    if (array.Length < 1 || !(array.GetValue(0) is IConvertible))
                    {
                        goto default;
                    }
                    rawValue = array.GetValue(0);
                }

                if (!(rawValue is IConvertible))
                {
                    goto default;
                }

                return(String.Format("ISO-{0:###0}", Convert.ToDecimal(rawValue)));
            }

            case ExifTag.Aperture:
            case ExifTag.MaxAperture:
            {
                // The actual aperture value of lens when the image was taken.
                // To convert this value to ordinary F-number(F-stop),
                // calculate this value's power of root 2 (=1.4142).
                // For example, if value is '5', F-number is 1.4142^5 = F5.6.
                double fStop = Math.Pow(2.0, Convert.ToDouble(rawValue) / 2.0);
                return(String.Format("f/{0:#0.0}", fStop));
            }

            case ExifTag.FNumber:
            {
                // The actual F-number (F-stop) of lens when the image was taken.
                return(String.Format("f/{0:#0.0}", Convert.ToDecimal(rawValue)));
            }

            case ExifTag.FocalLength:
            case ExifTag.FocalLengthIn35mmFilm:
            {
                return(String.Format("{0:#0.#} mm", Convert.ToDecimal(rawValue)));
            }

            case ExifTag.ShutterSpeed:
            {
                if (!(rawValue is Rational <int>))
                {
                    goto default;
                }

                // To convert this value to ordinary 'Shutter Speed';
                // calculate this value's power of 2, then reciprocal.
                // For example, if value is '4', shutter speed is 1/(2^4)=1/16 second.
                Rational <int> shutter = (Rational <int>)rawValue;

                if (shutter.Numerator > 0)
                {
                    double speed = Math.Pow(2.0, Convert.ToDouble(shutter));
                    return(String.Format("1/{0:####0} sec", speed));
                }
                else
                {
                    double speed = Math.Pow(2.0, -Convert.ToDouble(shutter));
                    return(String.Format("{0:####0.##} sec", speed));
                }
            }

            case ExifTag.ExposureTime:
            {
                if (!(rawValue is Rational <uint>))
                {
                    goto default;
                }

                // Exposure time (reciprocal of shutter speed). Unit is second.
                Rational <uint> exposure = (Rational <uint>)rawValue;

                if (exposure.Numerator < exposure.Denominator)
                {
                    exposure.Reduce();
                    return(String.Format("{0} sec", exposure));
                }
                else
                {
                    return(String.Format("{0:####0.##} sec", Convert.ToDecimal(rawValue)));
                }
            }

            case ExifTag.XResolution:
            case ExifTag.YResolution:
            case ExifTag.ThumbnailXResolution:
            case ExifTag.ThumbnailYResolution:
            case ExifTag.FocalPlaneXResolution:
            case ExifTag.FocalPlaneYResolution:
            {
                return(String.Format("{0:###0} dpi", Convert.ToDecimal(rawValue)));
            }

            case ExifTag.ImageHeight:
            case ExifTag.ImageWidth:
            case ExifTag.CompressedImageHeight:
            case ExifTag.CompressedImageWidth:
            case ExifTag.ThumbnailHeight:
            case ExifTag.ThumbnailWidth:
            {
                return(String.Format("{0:###0} pixels", Convert.ToDecimal(rawValue)));
            }

            case ExifTag.SubjectDistance:
            {
                return(String.Format("{0:###0.#} m", Convert.ToDecimal(rawValue)));
            }

            case ExifTag.ExposureBias:
            case ExifTag.Brightness:
            {
                string val;
                if (rawValue is Rational <int> )
                {
                    val = ((Rational <int>)rawValue).Numerator != 0 ? rawValue.ToString() : "0";
                }
                else
                {
                    val = Convert.ToDecimal(rawValue).ToString();
                }

                return(String.Format("{0} EV", val));
            }

            case ExifTag.CompressedBitsPerPixel:
            {
                return(String.Format("{0:###0.0} bits", Convert.ToDecimal(rawValue)));
            }

            case ExifTag.DigitalZoomRatio:
            {
                return(Convert.ToString(rawValue).Replace('/', ':'));
            }

            case ExifTag.GpsLatitude:
            case ExifTag.GpsLongitude:
            case ExifTag.GpsDestLatitude:
            case ExifTag.GpsDestLongitude:
            {
                if (!(rawValue is Array))
                {
                    goto default;
                }

                Array array = (Array)rawValue;
                if (array.Length < 1)
                {
                    return(String.Empty);
                }
                else if (array.Length != 3)
                {
                    goto default;
                }

                // attempt to use the GPSCoordinate XMP formatting guidelines
                GpsCoordinate gps = new GpsCoordinate();

                if (array.GetValue(0) is Rational <uint> )
                {
                    gps.Degrees = (Rational <uint>)array.GetValue(0);
                }
                else
                {
                    gps.SetDegrees(Convert.ToDecimal(array.GetValue(0)));
                }
                if (array.GetValue(1) is Rational <uint> )
                {
                    gps.Minutes = (Rational <uint>)array.GetValue(1);
                }
                else
                {
                    gps.SetMinutes(Convert.ToDecimal(array.GetValue(1)));
                }
                if (array.GetValue(2) is Rational <uint> )
                {
                    gps.Seconds = (Rational <uint>)array.GetValue(2);
                }
                else
                {
                    gps.SetSeconds(Convert.ToDecimal(array.GetValue(2)));
                }

                return(gps.ToString());
            }

            case ExifTag.GpsTimeStamp:
            {
                Array array = (Array)rawValue;
                if (array.Length < 1)
                {
                    return(String.Empty);
                }

                string[] time = new string[array.Length];
                for (int i = 0; i < array.Length; i++)
                {
                    time[i] = Convert.ToDecimal(array.GetValue(i)).ToString();
                }
                return(String.Join(":", time));
            }

            default:
            {
                if (rawValue is Enum)
                {
                    string description = Utility.GetDescription((Enum)rawValue);
                    if (!String.IsNullOrEmpty(description))
                    {
                        return(description);
                    }
                }
                else if (rawValue is Array)
                {
                    Array array = (Array)rawValue;
                    if (array.Length < 1)
                    {
                        return(String.Empty);
                    }

                    Type type = array.GetValue(0).GetType();
                    if (!type.IsPrimitive || type == typeof(char) || type == typeof(float) || type == typeof(double))
                    {
                        return(Convert.ToString(rawValue));
                    }

                    //const int ElemsPerRow = 40;
                    int           charSize = 2 * System.Runtime.InteropServices.Marshal.SizeOf(type);
                    string        format   = "{0:X" + (charSize) + "}";
                    StringBuilder builder  = new StringBuilder(((charSize + 1) * array.Length) /*+(2*array.Length/ElemsPerRow)*/);
                    for (int i = 0; i < array.Length; i++)
                    {
                        if (i > 0)
                        {
                            //if ((i+1)%ElemsPerRow == 0)
                            //{
                            //    builder.AppendLine();
                            //}
                            //else
                            {
                                builder.Append(" ");
                            }
                        }

                        builder.AppendFormat(format, array.GetValue(i));
                    }
                    return(builder.ToString());
                }

                return(Convert.ToString(rawValue));
            }
            }
        }
Beispiel #3
0
        /// <summary>
        /// Consolidates EXIF GPS values into XMP style
        /// </summary>
        /// <param name="gps"></param>
        /// <param name="priority"></param>
        /// <returns></returns>
        private IEnumerable <XmpProperty> ProcessGps(IEnumerable <XmpProperty> gps, decimal priority)
        {
            GpsCoordinate latitude = null, longitude = null, destLatitude = null, destLongitude = null;
            string        latitudeRef = null, longitudeRef = null, destLatitudeRef = null, destLongitudeRef = null;

            foreach (XmpProperty property in gps)
            {
                if (!(property.Schema is ExifSchema))
                {
                    yield return(property);

                    continue;
                }

                switch ((ExifSchema)property.Schema)
                {
                case ExifSchema.GPSLatitude:
                {
                    GpsCoordinate.TryParse(Convert.ToString(property.Value), out latitude);
                    break;
                }

                case ExifSchema.GPSLatitudeRef:
                {
                    latitudeRef = Convert.ToString(property.Value);
                    break;
                }

                case ExifSchema.GPSLongitude:
                {
                    GpsCoordinate.TryParse(Convert.ToString(property.Value), out longitude);
                    break;
                }

                case ExifSchema.GPSLongitudeRef:
                {
                    longitudeRef = Convert.ToString(property.Value);
                    break;
                }

                case ExifSchema.GPSDestLatitude:
                {
                    GpsCoordinate.TryParse(Convert.ToString(property.Value), out destLatitude);
                    break;
                }

                case ExifSchema.GPSDestLatitudeRef:
                {
                    destLatitudeRef = Convert.ToString(property.Value);
                    break;
                }

                case ExifSchema.GPSDestLongitude:
                {
                    GpsCoordinate.TryParse(Convert.ToString(property.Value), out destLongitude);
                    break;
                }

                case ExifSchema.GPSDestLongitudeRef:
                {
                    destLongitudeRef = Convert.ToString(property.Value);
                    break;
                }

                case ExifSchema.GPSDateStamp:
                case ExifSchema.GPSTimeStamp:

                case ExifSchema.GPSAltitude:
                case ExifSchema.GPSAltitudeRef:

                case ExifSchema.GPSDestBearing:
                case ExifSchema.GPSDestBearingRef:

                case ExifSchema.GPSDestDistance:
                case ExifSchema.GPSDestDistanceRef:

                case ExifSchema.GPSImgDirection:
                case ExifSchema.GPSImgDirectionRef:

                case ExifSchema.GPSSpeed:
                case ExifSchema.GPSSpeedRef:

                case ExifSchema.GPSTrack:
                case ExifSchema.GPSTrackRef:
                default:
                {
                    // TODO: process other dual properties
                    yield return(property);

                    break;
                }
                }
            }

            if (latitude != null)
            {
                if (!String.IsNullOrEmpty(latitudeRef))
                {
                    latitude.Direction = latitudeRef;
                }

                yield return(new XmpProperty
                {
                    Schema = ExifSchema.GPSLatitude,
                    Value = latitude.ToString("X"),
                    Priority = priority
                });
            }

            if (longitude != null)
            {
                if (!String.IsNullOrEmpty(longitudeRef))
                {
                    longitude.Direction = longitudeRef;
                }

                yield return(new XmpProperty
                {
                    Schema = ExifSchema.GPSLongitude,
                    Value = longitude.ToString("X"),
                    Priority = priority
                });
            }

            if (destLatitude != null)
            {
                if (!String.IsNullOrEmpty(destLatitudeRef))
                {
                    destLatitude.Direction = destLatitudeRef;
                }

                yield return(new XmpProperty
                {
                    Schema = ExifSchema.GPSDestLatitude,
                    Value = destLatitude.ToString("X"),
                    Priority = priority
                });
            }

            if (destLongitude != null)
            {
                if (!String.IsNullOrEmpty(destLongitudeRef))
                {
                    destLongitude.Direction = destLongitudeRef;
                }

                yield return(new XmpProperty
                {
                    Schema = ExifSchema.GPSDestLongitude,
                    Value = destLongitude.ToString("X"),
                    Priority = priority
                });
            }
        }
Beispiel #4
0
        /// <summary>
        /// Converts EXIF / TIFF values into XMP style
        /// </summary>
        /// <param name="property"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        private object ProcessValue(XmpProperty property, object value)
        {
            if (value == null)
            {
                return(value);
            }

            if (property.ValueType is XmpBasicType)
            {
                switch ((XmpBasicType)property.ValueType)
                {
                case XmpBasicType.Date:
                {
                    DateTime date;

                    Array array = value as Array;
                    if (array != null && array.Length == 3)
                    {
                        try
                        {
                            var seconds =
                                60m * (60m * Convert.ToDecimal(this.ProcessRational(property, array.GetValue(0))) +
                                       Convert.ToDecimal(this.ProcessRational(property, array.GetValue(1)))) +
                                Convert.ToDecimal(this.ProcessRational(property, array.GetValue(2)));

                            date  = DateTime.MinValue.AddSeconds(Convert.ToDouble(seconds));
                            value = date.ToString(XmpDateFormat);
                        }
                        catch { }
                    }
                    else if (DateTime.TryParseExact(
                                 Convert.ToString(value),
                                 ExifDateFormats,
                                 DateTimeFormatInfo.InvariantInfo,
                                 DateTimeStyles.AssumeLocal,
                                 out date))
                    {
                        // clean up to ISO-8601
                        value = date.ToString(XmpDateFormat);
                    }
                    break;
                }

                case XmpBasicType.LangAlt:
                case XmpBasicType.Text:
                case XmpBasicType.ProperName:
                {
                    if (value is byte[])
                    {
                        if (property.Schema is ExifSchema &&
                            ((ExifSchema)property.Schema) == ExifSchema.GPSVersionID)
                        {
                            // GPSVersionID represents version as byte[]
                            value = String.Join(".", ((byte[])value).Select(b => b.ToString()).ToArray());
                        }
                        else
                        {
                            value = new String(Encoding.UTF8.GetChars((byte[])value));
                        }

                        value = this.TrimNullTerm((string)value);
                    }
                    else if (!(value is string) && value is IEnumerable)
                    {
                        var strList = ((IEnumerable)value).OfType <string>().Select(str => this.TrimNullTerm(str)).Where(str => !String.IsNullOrEmpty(str));

                        if (property.Quantity == XmpQuantity.Single)
                        {
                            value = strList.FirstOrDefault();
                        }
                        else
                        {
                            value = strList;
                        }
                    }
                    else if (value is string)
                    {
                        value = this.TrimNullTerm((string)value);
                    }
                    break;
                }
                }
            }
            else if (property.ValueType is ExifType)
            {
                switch ((ExifType)property.ValueType)
                {
                case ExifType.GpsCoordinate:
                {
                    Array array = value as Array;
                    if (array != null && array.Length == 3)
                    {
                        try
                        {
                            GpsCoordinate gps = new GpsCoordinate();
                            gps.Degrees = (Rational <uint>) this.ProcessRational(property, array.GetValue(0));
                            gps.Minutes = (Rational <uint>) this.ProcessRational(property, array.GetValue(1));
                            gps.Seconds = (Rational <uint>) this.ProcessRational(property, array.GetValue(2));
                            value       = gps.ToString("X");
                        }
                        catch { }
                    }
                    break;
                }

                case ExifType.Rational:
                {
                    Array array = value as Array;
                    if (array == null)
                    {
                        value = Convert.ToString(this.ProcessRational(property, value));
                    }
                    else
                    {
                        string[] strArray = new string[array.Length];
                        for (int i = 0; i < array.Length; i++)
                        {
                            strArray[i] = Convert.ToString(this.ProcessRational(property, array.GetValue(i)));
                        }
                        value = array;
                    }
                    break;
                }

                case ExifType.Flash:
                {
                    ExifTagFlash flash;
                    if (value is ushort)
                    {
                        flash = (ExifTagFlash)value;
                    }
                    else if (value is string)
                    {
                        try
                        {
                            flash = (ExifTagFlash)Enum.Parse(typeof(ExifTagFlash), Convert.ToString(value));
                        }
                        catch
                        {
                            break;
                        }
                    }
                    else
                    {
                        break;
                    }

                    value = new Dictionary <string, object>
                    {
                        { "Fired", Convert.ToString((flash & ExifTagFlash.FlashFired) == ExifTagFlash.FlashFired) },
                        { "Return", (int)(flash & (ExifTagFlash.ReturnNotDetected | ExifTagFlash.ReturnDetected)) >> 1 },
                        { "Mode", (int)(flash & (ExifTagFlash.ModeOn | ExifTagFlash.ModeOff | ExifTagFlash.ModeAuto)) >> 3 },
                        { "Function", Convert.ToString((flash & ExifTagFlash.NoFlashFunction) == ExifTagFlash.NoFlashFunction) },
                        { "RedEyeMode", Convert.ToString((flash & ExifTagFlash.RedEyeReduction) == ExifTagFlash.RedEyeReduction) }
                    };
                    break;
                }
                }
            }

            return(value);
        }