Program.cs 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Diagnostics;
  4. using System.Drawing.Imaging;
  5. using System.Drawing;
  6. using System.IO;
  7. using System.Text;
  8. using System.Text.RegularExpressions;
  9. namespace PhotoSorter
  10. {
  11. class Program
  12. {
  13. static void Main(string[] args)
  14. {
  15. Console.WriteLine("This application can sort photos in CURRENT directory by EXIF shotdate Or it's Filename, move the photos to a NEW sub-Directory which created by date like \"2017-10-01\". Hansi 2017-10-21");
  16. Console.WriteLine("Press any key to DO it...");
  17. Console.ReadKey();
  18. string folderIn = AppDomain.CurrentDomain.BaseDirectory;
  19. string[] extArray = new string[] {".jpg",".jpeg",".dng",".nef"};
  20. doWork(folderIn, extArray);
  21. Console.WriteLine("Done!");
  22. Console.ReadKey();
  23. }
  24. static void doWork(string folderIn,string[] extArr)
  25. {
  26. for (int exti = 0; exti < extArr.Length; exti++)
  27. {
  28. Console.WriteLine("---------Working with " + extArr[exti] + " files!--------------");
  29. var files = Directory.GetFiles(folderIn, "*" + extArr[exti], SearchOption.TopDirectoryOnly);
  30. int k = 0;
  31. Console.WriteLine("Total:" + files.Length.ToString());
  32. foreach (var file in files)
  33. {
  34. k++;
  35. FileInfo fi = new FileInfo(file);
  36. Console.WriteLine(k.ToString() + "/" + files.Length.ToString() + "\t" + fi.Name);
  37. string newFileName;
  38. if ((fi.Attributes & FileAttributes.Hidden) != FileAttributes.Hidden)
  39. {
  40. var dateTaken = GetDateTakenFromImage(file);
  41. if (dateTaken == DateTime.MinValue)
  42. {
  43. Console.WriteLine("ignore " + fi.Name + ":Get Exif Fail");
  44. Console.WriteLine("Trying to get Date From filename...");
  45. dateTaken = GetDateFromImageFileName(file);
  46. if (dateTaken == DateTime.MinValue)
  47. {
  48. Console.WriteLine("ignore " + fi.Name + ":Get Date By File Name Fail");
  49. continue;
  50. }
  51. }
  52. //dateTaken = dateTaken.AddHours(hourOffset);
  53. //dateTaken = dateTaken.AddMonths(monthOffset);
  54. var newDir = Path.Combine(Path.GetDirectoryName(file), dateTaken.ToString("yyyy-MM-dd"));
  55. newFileName = Path.Combine(newDir, Path.GetFileName(file));
  56. if (!Directory.Exists(Path.GetDirectoryName(newFileName)))
  57. {
  58. Directory.CreateDirectory(Path.GetDirectoryName(newFileName));
  59. }
  60. //newFileName = Path.Combine(Path.GetDirectoryName(file), dateTaken.ToString("yyyy-MM-dd HHmm.ss") + " " + postfix + ".jpg");
  61. if (file != newFileName)
  62. {
  63. int i = 1;
  64. while (File.Exists(newFileName))
  65. {
  66. newFileName = Path.Combine(Path.GetDirectoryName(file), dateTaken.ToString("yyyy-MM-dd HHmm.ss") + " " + i++ + ".jpg");
  67. }
  68. Debug.Assert(!File.Exists(newFileName));
  69. File.Move(file, newFileName);
  70. }
  71. }
  72. }
  73. }
  74. }
  75. /// <summary>
  76. /// We init this once so that if the function is repeatedly called
  77. /// It isn't stressing the garbage man
  78. /// </summary>
  79. private static Regex r = new Regex(":");
  80. /// <summary>
  81. /// Retrieves the datetime WITHOUT loading the whole image
  82. /// </summary>
  83. /// <param name="path"></param>
  84. /// <returns></returns>
  85. public static DateTime GetDateTakenFromImage(string path)
  86. {
  87. try
  88. {
  89. using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read))
  90. using (Image myImage = Image.FromStream(fs, false, false))
  91. {
  92. PropertyItem propItem = myImage.GetPropertyItem(36867);
  93. string dateTaken = r.Replace(Encoding.UTF8.GetString(propItem.Value), "-", 2);
  94. return DateTime.Parse(dateTaken);
  95. }
  96. }
  97. catch (Exception ex)
  98. {
  99. Console.WriteLine(ex.Message);
  100. return DateTime.MinValue;
  101. }
  102. }
  103. public static DateTime GetDateFromImageFileName(string path)
  104. {
  105. //not finished try to get name from filename. yyyyMMdd or yyyy-MM-dd
  106. string fn = Path.GetFileNameWithoutExtension(path);
  107. Regex r1 = new Regex(@"20\d{6}");
  108. Regex r2 = new Regex(@"20\d{2}-\d{2}-\d{2}");
  109. if (r1.IsMatch(fn))
  110. {
  111. string ff = r1.Match(fn).Value;
  112. return DateTime.Parse(ff.Substring(0,4)+"/" + ff.Substring(4,2) + "/" + ff.Substring(6,2));
  113. }
  114. if (r2.IsMatch(fn))
  115. {
  116. string ff = r2.Match(fn).Value;
  117. return DateTime.Parse(ff);
  118. }
  119. return DateTime.MinValue;
  120. }
  121. }
  122. }