/// <summary> /// Writes XMP data to a file /// </summary> /// <param name="filepath">Path to file</param> /// <param name="values">XMP values to be written</param> public static void WriteXMPMetadata(string filepath, XMP xmp) { //TODO: make XMP write faster (like thumbnail read) SetProcess("", ExifArgument.Metadata); string command = String.Empty; bool run = false; Dictionary<string, XMP.XMPentry> values = xmp.Values; CultureInfo culture = new CultureInfo("en-US"); for (int i = 0; i < values.Count; i++) { if (ProjectManager.CurrentProject.MainWorker.CancellationPending) { return; } XMP.XMPentry entry = values.ElementAt(i).Value; string nc = "-xmp:" + entry.Name + "=" + entry.Value.ToString() + " "; if (i == 0) { nc += "-xmp:ProcessVersion=" + xmp.FileVersion + " "; nc += "-xmp:Exposure2012=" + xmp.NewExposure.ToString("F4", culture) + " "; } //the windows command line can't take longer commands than 8191 characters if (command.Length + nc.Length + filepath.Length < 8191) { command += nc; } else { run = true; i--; } if (run || i == values.Count - 1) { exiftool.StartInfo.Arguments = "-m " + command + "\"" + filepath + "\""; exiftool.Start(); exiftool.WaitForExit(); run = false; } } exiftool.Dispose(); }
/// <summary> /// Add a XMP keyframe /// </summary> /// <param name="path">Path to the XMP file</param> /// <param name="index">Index where the keyframe is set</param> internal override void AddKeyframe(int index, string path) { if (index < 0 && index >= Frames.Count) { throw new ArgumentException("Index too high or low"); } XMP nxmp = new XMP(path); if (Frames.Any(t => (((FrameACR)t).XMPFile == null) ? false : ((FrameACR)t).XMPFile.FileVersion != nxmp.FileVersion)) { throw new FileVersionException("Different XMP version than previously added XMP's"); } ((FrameACR)Frames[index]).XMPFile = new XMP(path); Frames[index].IsKeyframe = true; }
protected override void WriteFiles() { XMP[] nxmp; double[] ys = new double[Frames.Count]; if (KeyframeCount > 1) { nxmp = Interpolation.Do(this); double[] y = Frames.Where(t => t.IsKeyframe).Select(t => ((FrameACR)t).XMPFile.Exposure).ToArray(); double[] x = new double[y.Length]; int k = 0; for (int j = 0; j < Frames.Count; j++) { if (Frames[j].IsKeyframe) { x[k] = j; k++; } } ys = Interpolation.Do(x, y, Frames.Count); } else { XMP firstxmp = ((FrameACR)Frames.First(t => t.IsKeyframe)).XMPFile; nxmp = new XMP[Frames.Count]; for (int j = 0; j < Frames.Count; j++) { nxmp[j] = firstxmp.Copy(); nxmp[j].Path = ((FrameACR)Frames[j]).XMPFile.Path; ys[j] = firstxmp.Exposure; } } for (int i = 0; i < nxmp.Length; i++) { if (IsBrightnessCalculated) { if (i == 0 || i == nxmp.Length - 1) { nxmp[i].NewExposure = (ys[i] > 10) ? 10 : (ys[i] < -5) ? -5 : ys[i]; } else { nxmp[i].NewExposure = Math.Log(Frames[i].NewBrightness / Frames[i].AlternativeBrightness, 2) + ((ys[i] > 5) ? 5 : (ys[i] < -5) ? -5 : ys[i]); if (double.IsNaN(nxmp[i].NewExposure)) { throw new NotFiniteNumberException(); } } } else { nxmp[i].NewExposure = (ys[i] > 5) ? 5 : (ys[i] < -5) ? -5 : ys[i]; } nxmp[i].Write(); MainWorker.ReportProgress(0, new ProgressChangeEventArgs(i * 100 / (nxmp.Length - 1), ProgressType.WriteXMP)); } }
/// <summary> /// Copies all values /// </summary> /// <returns>a new XMP with values duplicated from this XMP</returns> public XMP Copy() { XMP output = new XMP(); output.Path = this.Path; output.FileVersion = this.FileVersion; output.Exposure = this.Exposure; output.NewExposure = this.NewExposure; output.Values = new Dictionary <string, XMPentry>(this.Values); return(output); }
/// <summary> /// Init a new CameraRaw frame /// </summary> /// <param name="FilePath">Path to the image file</param> public FrameACR(string FilePath) : base(FilePath) { XMPFile = new XMP(FilePath); }
internal static XMP[] Do(ProjectACR CurProj) { XMP[] Output = new XMP[CurProj.Frames.Count]; XMP typexmp = ((FrameACR)CurProj.Frames.First(t => t.IsKeyframe)).XMPFile; for (int j = 0; j < CurProj.Frames.Count; j++) { Output[j] = typexmp.Copy(); } for (int i = 0; i < typexmp.Values.Count; i++) { List<KeyValuePair<int, object>> Values = new List<KeyValuePair<int, object>>(); Type CurType = typexmp.Values.ElementAt(i).Value.type; string valname = typexmp.Values.ElementAt(i).Key; for (int j = 0; j < CurProj.Frames.Count; j++) { if (CurProj.Frames[j].IsKeyframe) { Values.Add(new KeyValuePair<int, object>(j, ((FrameACR)CurProj.Frames[j]).XMPFile.Values[valname].Value)); } else if (j == 0) { Values.Add(new KeyValuePair<int, object>(j, ((FrameACR)CurProj.Frames.First(t => t.IsKeyframe)).XMPFile.Values[valname].Value)); } else if (j == CurProj.Frames.Count - 1) { Values.Add(new KeyValuePair<int, object>(j, ((FrameACR)CurProj.Frames.Last(t => t.IsKeyframe)).XMPFile.Values[valname].Value)); } } if (CurType != typeof(bool) && CurType != typeof(string)) { PointD[] InVals = new PointD[Values.Count]; PointD[] OutVals = new PointD[CurProj.Frames.Count]; if (CurType == typeof(int)) { for (int k = 0; k < Values.Count; k++) { InVals[k] = new PointD(Values[k].Key, (int)Convert.ChangeType(Values[k].Value, typeof(int))); } OutVals = Do(InVals, CurProj.Frames.Count); for (int k = 0; k < CurProj.Frames.Count; k++) { if (((FrameACR)CurProj.Frames[k]).XMPFile != null) { Output[k].Path = ((FrameACR)CurProj.Frames[k]).XMPFile.Path; Output[k].Exposure = ((FrameACR)CurProj.Frames[k]).XMPFile.Exposure; Output[k].FileVersion = ((FrameACR)CurProj.Frames[k]).XMPFile.FileVersion; Output[k].NewExposure = ((FrameACR)CurProj.Frames[k]).XMPFile.NewExposure; } Output[k].Values[valname] = new XMP.XMPentry(typexmp.Values[valname].Name, (int)OutVals[k].Y, typeof(int), typexmp.Values[valname].sign, typexmp.Values[valname].min, typexmp.Values[valname].max); } } else if (CurType == typeof(double)) { for (int k = 0; k < Values.Count; k++) { InVals[k] = new PointD(Values[k].Key, (float)Convert.ChangeType(Values[k].Value, typeof(float))); } OutVals = Do(InVals, CurProj.Frames.Count); for (int k = 0; k < CurProj.Frames.Count; k++) { if (((FrameACR)CurProj.Frames[k]).XMPFile != null) { Output[k].Path = ((FrameACR)CurProj.Frames[k]).XMPFile.Path; Output[k].Exposure = ((FrameACR)CurProj.Frames[k]).XMPFile.Exposure; Output[k].FileVersion = ((FrameACR)CurProj.Frames[k]).XMPFile.FileVersion; Output[k].NewExposure = ((FrameACR)CurProj.Frames[k]).XMPFile.NewExposure; } Output[k].Values[valname] = new XMP.XMPentry(typexmp.Values[valname].Name, OutVals[k].Y, typeof(double), typexmp.Values[valname].sign, typexmp.Values[valname].min, typexmp.Values[valname].max); } } else { throw new InterpolationNotPossibleException("Couldn't interpolate this kind of Value: " + CurType.FullName); } } else { int index = 0; for (int k = 0; k < CurProj.Frames.Count; k++) { if (((FrameACR)CurProj.Frames[k]).XMPFile != null) { Output[k].Path = ((FrameACR)CurProj.Frames[k]).XMPFile.Path; Output[k].Exposure = ((FrameACR)CurProj.Frames[k]).XMPFile.Exposure; Output[k].FileVersion = ((FrameACR)CurProj.Frames[k]).XMPFile.FileVersion; Output[k].NewExposure = ((FrameACR)CurProj.Frames[k]).XMPFile.NewExposure; } Output[k].Values[valname] = new XMP.XMPentry(typexmp.Values[valname].Name, Values[index].Value, CurType, typexmp.Values[valname].sign, typexmp.Values[valname].min, typexmp.Values[valname].max); if (Values[index].Key == k) { index++; } } } } return Output; }
/// <summary> /// Copies all values /// </summary> /// <returns>a new XMP with values duplicated from this XMP</returns> public XMP Copy() { XMP output = new XMP(); output.Path = this.Path; output.FileVersion = this.FileVersion; output.Exposure = this.Exposure; output.NewExposure = this.NewExposure; output.Values = new Dictionary<string, XMPentry>(this.Values); return output; }
internal static XMP[] Do(ProjectACR CurProj) { XMP[] Output = new XMP[CurProj.Frames.Count]; XMP typexmp = ((FrameACR)CurProj.Frames.First(t => t.IsKeyframe)).XMPFile; for (int j = 0; j < CurProj.Frames.Count; j++) { Output[j] = typexmp.Copy(); } for (int i = 0; i < typexmp.Values.Count; i++) { List <KeyValuePair <int, object> > Values = new List <KeyValuePair <int, object> >(); Type CurType = typexmp.Values.ElementAt(i).Value.type; string valname = typexmp.Values.ElementAt(i).Key; for (int j = 0; j < CurProj.Frames.Count; j++) { if (CurProj.Frames[j].IsKeyframe) { Values.Add(new KeyValuePair <int, object>(j, ((FrameACR)CurProj.Frames[j]).XMPFile.Values[valname].Value)); } else if (j == 0) { Values.Add(new KeyValuePair <int, object>(j, ((FrameACR)CurProj.Frames.First(t => t.IsKeyframe)).XMPFile.Values[valname].Value)); } else if (j == CurProj.Frames.Count - 1) { Values.Add(new KeyValuePair <int, object>(j, ((FrameACR)CurProj.Frames.Last(t => t.IsKeyframe)).XMPFile.Values[valname].Value)); } } if (CurType != typeof(bool) && CurType != typeof(string)) { PointD[] InVals = new PointD[Values.Count]; PointD[] OutVals = new PointD[CurProj.Frames.Count]; if (CurType == typeof(int)) { for (int k = 0; k < Values.Count; k++) { InVals[k] = new PointD(Values[k].Key, (int)Convert.ChangeType(Values[k].Value, typeof(int))); } OutVals = Do(InVals, CurProj.Frames.Count); for (int k = 0; k < CurProj.Frames.Count; k++) { if (((FrameACR)CurProj.Frames[k]).XMPFile != null) { Output[k].Path = ((FrameACR)CurProj.Frames[k]).XMPFile.Path; Output[k].Exposure = ((FrameACR)CurProj.Frames[k]).XMPFile.Exposure; Output[k].FileVersion = ((FrameACR)CurProj.Frames[k]).XMPFile.FileVersion; Output[k].NewExposure = ((FrameACR)CurProj.Frames[k]).XMPFile.NewExposure; } Output[k].Values[valname] = new XMP.XMPentry(typexmp.Values[valname].Name, (int)OutVals[k].Y, typeof(int), typexmp.Values[valname].sign, typexmp.Values[valname].min, typexmp.Values[valname].max); } } else if (CurType == typeof(double)) { for (int k = 0; k < Values.Count; k++) { InVals[k] = new PointD(Values[k].Key, (float)Convert.ChangeType(Values[k].Value, typeof(float))); } OutVals = Do(InVals, CurProj.Frames.Count); for (int k = 0; k < CurProj.Frames.Count; k++) { if (((FrameACR)CurProj.Frames[k]).XMPFile != null) { Output[k].Path = ((FrameACR)CurProj.Frames[k]).XMPFile.Path; Output[k].Exposure = ((FrameACR)CurProj.Frames[k]).XMPFile.Exposure; Output[k].FileVersion = ((FrameACR)CurProj.Frames[k]).XMPFile.FileVersion; Output[k].NewExposure = ((FrameACR)CurProj.Frames[k]).XMPFile.NewExposure; } Output[k].Values[valname] = new XMP.XMPentry(typexmp.Values[valname].Name, OutVals[k].Y, typeof(double), typexmp.Values[valname].sign, typexmp.Values[valname].min, typexmp.Values[valname].max); } } else { throw new InterpolationNotPossibleException("Couldn't interpolate this kind of Value: " + CurType.FullName); } } else { int index = 0; for (int k = 0; k < CurProj.Frames.Count; k++) { if (((FrameACR)CurProj.Frames[k]).XMPFile != null) { Output[k].Path = ((FrameACR)CurProj.Frames[k]).XMPFile.Path; Output[k].Exposure = ((FrameACR)CurProj.Frames[k]).XMPFile.Exposure; Output[k].FileVersion = ((FrameACR)CurProj.Frames[k]).XMPFile.FileVersion; Output[k].NewExposure = ((FrameACR)CurProj.Frames[k]).XMPFile.NewExposure; } Output[k].Values[valname] = new XMP.XMPentry(typexmp.Values[valname].Name, Values[index].Value, CurType, typexmp.Values[valname].sign, typexmp.Values[valname].min, typexmp.Values[valname].max); if (Values[index].Key == k) { index++; } } } } return(Output); }