|
@@ -1,6 +1,11 @@
|
|
using System;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Collections.Generic;
|
|
|
|
+using System.Diagnostics;
|
|
|
|
+using System.Drawing.Imaging;
|
|
|
|
+using System.Drawing;
|
|
|
|
+using System.IO;
|
|
using System.Text;
|
|
using System.Text;
|
|
|
|
+using System.Text.RegularExpressions;
|
|
|
|
|
|
namespace PhotoSorter
|
|
namespace PhotoSorter
|
|
{
|
|
{
|
|
@@ -8,6 +13,98 @@ namespace PhotoSorter
|
|
{
|
|
{
|
|
static void Main(string[] args)
|
|
static void Main(string[] args)
|
|
{
|
|
{
|
|
|
|
+ string postfix = "Hansi";
|
|
|
|
+
|
|
|
|
+ Console.WriteLine("This application can sort photos in CURRENT directory by exif shotdate, move the photos to sub-Directory which created by date. Hansi 2017-10-01");
|
|
|
|
+ Console.WriteLine("Press any key to DO it...");
|
|
|
|
+ Console.ReadKey();
|
|
|
|
+ string folderIn = AppDomain.CurrentDomain.BaseDirectory;
|
|
|
|
+ //int hourOffset = 1;
|
|
|
|
+ //int monthOffset = -1;
|
|
|
|
+
|
|
|
|
+ var files = Directory.GetFiles(folderIn, "*.jpg", SearchOption.AllDirectories);
|
|
|
|
+ int k = 0;
|
|
|
|
+ Console.WriteLine("Total:" + files.Length.ToString());
|
|
|
|
+ foreach (var file in files)
|
|
|
|
+ {
|
|
|
|
+ k++;
|
|
|
|
+ Console.WriteLine(k.ToString() + "/" + files.Length.ToString());
|
|
|
|
+
|
|
|
|
+ FileInfo fi = new FileInfo(file);
|
|
|
|
+
|
|
|
|
+ string newFileName;
|
|
|
|
+ if ((fi.Attributes & FileAttributes.Hidden) != FileAttributes.Hidden)
|
|
|
|
+ {
|
|
|
|
+ var dateTaken = GetDateTakenFromImage(file);
|
|
|
|
+ if (dateTaken == DateTime.MinValue)
|
|
|
|
+ {
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+ if (Path.GetExtension(file) != ".jpg")
|
|
|
|
+ {
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+ //dateTaken = dateTaken.AddHours(hourOffset);
|
|
|
|
+ //dateTaken = dateTaken.AddMonths(monthOffset);
|
|
|
|
+
|
|
|
|
+ var newDir = Path.Combine(Path.GetDirectoryName(file), dateTaken.ToString("yyyy-MM-dd"));
|
|
|
|
+
|
|
|
|
+ newFileName = Path.Combine(newDir, Path.GetFileName(file));
|
|
|
|
+
|
|
|
|
+ if (!Directory.Exists(Path.GetDirectoryName(newFileName)))
|
|
|
|
+ {
|
|
|
|
+ Directory.CreateDirectory(Path.GetDirectoryName(newFileName));
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ //newFileName = Path.Combine(Path.GetDirectoryName(file), dateTaken.ToString("yyyy-MM-dd HHmm.ss") + " " + postfix + ".jpg");
|
|
|
|
+
|
|
|
|
+ if (file != newFileName)
|
|
|
|
+ {
|
|
|
|
+ int i = 1;
|
|
|
|
+ while (File.Exists(newFileName))
|
|
|
|
+ {
|
|
|
|
+ newFileName = Path.Combine(Path.GetDirectoryName(file), dateTaken.ToString("yyyy-MM-dd HHmm.ss") + " " + i++ + " " + postfix + ".jpg");
|
|
|
|
+ }
|
|
|
|
+ Debug.Assert(!File.Exists(newFileName));
|
|
|
|
+
|
|
|
|
+ File.Move(file, newFileName);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ Console.WriteLine("Done!");
|
|
|
|
+ Console.ReadKey();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /// <summary>
|
|
|
|
+ /// We init this once so that if the function is repeatedly called
|
|
|
|
+ /// It isn't stressing the garbage man
|
|
|
|
+ /// </summary>
|
|
|
|
+ private static Regex r = new Regex(":");
|
|
|
|
+
|
|
|
|
+ /// <summary>
|
|
|
|
+ /// Retrieves the datetime WITHOUT loading the whole image
|
|
|
|
+ /// </summary>
|
|
|
|
+ /// <param name="path"></param>
|
|
|
|
+ /// <returns></returns>
|
|
|
|
+ public static DateTime GetDateTakenFromImage(string path)
|
|
|
|
+ {
|
|
|
|
+ using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read))
|
|
|
|
+ using (Image myImage = Image.FromStream(fs, false, false))
|
|
|
|
+ {
|
|
|
|
+ try
|
|
|
|
+ {
|
|
|
|
+ PropertyItem propItem = myImage.GetPropertyItem(36867);
|
|
|
|
+ string dateTaken = r.Replace(Encoding.UTF8.GetString(propItem.Value), "-", 2);
|
|
|
|
+ return DateTime.Parse(dateTaken);
|
|
|
|
+ }
|
|
|
|
+ catch (ArgumentException ex)
|
|
|
|
+ {
|
|
|
|
+ return DateTime.MinValue;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+
|
|
}
|
|
}
|
|
}
|
|
}
|