none
изменить дату съемки файла C# RRS feed

  • Вопрос

  • Пытаюсь изменить Дату съемки у файла(изображения) 

    using (System.IO.Stream savedFile = System.IO.File.Open(filename, System.IO.FileMode.Open, System.IO.FileAccess.ReadWrite))
    {
       System.Windows.Media.Imaging.BitmapDecoder output = System.Windows.Media.Imaging.BitmapDecoder.Create(savedFile,  System.Windows.Media.Imaging.BitmapCreateOptions.None, System.Windows.Media.Imaging.BitmapCacheOption.Default);
       System.Windows.Media.Imaging.InPlaceBitmapMetadataWriter bitmapMetadata = output.Frames[0].CreateInPlaceBitmapMetadataWriter();
    
       bitmapMetadata.DateTaken = Date.ToString("M/d/yyyy HH:mm:ss");
       bitmapMetadata.SetQuery(DATE_TAKEN_QUERY, Date.ToString("yyyy:MM:dd HH:mm:ss"));
       bitmapMetadata.SetQuery(DIGITIZED_DATE_QUERY, Date.ToString("yyyy:MM:dd HH:mm:ss"));
       bitmapMetadata.SetQuery(ORIGINAL_DATE_QUERY, Date.ToString("yyyy:MM:dd HH:mm:ss"));
       if (!bitmapMetadata.TrySave())
       {  
          inPlaceSuccessful = true;
       }
    }

    Это работает но не для всех файлов. 

    bitmapMetadata.TrySave() иногда возвращает false

    Может существуют другие способы?

Ответы

  • private const string DATE_TAKEN_QUERY = "/app1/ifd/{ushort=306}";
    private const string ORIGINAL_DATE_QUERY = "/app1/ifd/exif/{ushort=36867}";
    private const string DIGITIZED_DATE_QUERY = "/app1/ifd/exif/{ushort=36868}";
    private const string LATITUDE_QUERY = "/app1/ifd/gps/subifd:{ulong=2}";
    private const string LONGITUDE_QUERY = "/app1/ifd/gps/subifd:{ulong=4}";
    private const string NORTH_OR_SOUTH_QUERY = "/app1/ifd/gps/subifd:{char=1}";
    private const string EAST_OR_WEST_QUERY = "/app1/ifd/gps/subifd:{char=3}";
    private const string GPS_VERSION_QUERY = "/app1/ifd/gps/";
    private const string IPTC_KEYWORDS_QUERY = "/app13/irb/8bimiptc/iptc/keywords";

    using (System.IO.Stream savedFile = System.IO.File.Open(filename, System.IO.FileMode.Open, System.IO.FileAccess.ReadWrite)) { bool inPlaceSuccessful = false; System.Windows.Media.Imaging.BitmapDecoder output = System.Windows.Media.Imaging.BitmapDecoder.Create(savedFile, System.Windows.Media.Imaging.BitmapCreateOptions.None, System.Windows.Media.Imaging.BitmapCacheOption.Default); System.Windows.Media.Imaging.InPlaceBitmapMetadataWriter bitmapMetadata = output.Frames[0].CreateInPlaceBitmapMetadataWriter(); if (!bitmapMetadata.TrySave()) // проверяем можно ли сохранить изменения { bitmapMetadata.DateTaken = Date.ToString("M/d/yyyy HH:mm:ss"); bitmapMetadata.SetQuery(DATE_TAKEN_QUERY, Date.ToString("yyyy:MM:dd HH:mm:ss")); bitmapMetadata.SetQuery(DIGITIZED_DATE_QUERY, Date.ToString("yyyy:MM:dd HH:mm:ss")); bitmapMetadata.SetQuery(ORIGINAL_DATE_QUERY, Date.ToString("yyyy:MM:dd HH:mm:ss")); inPlaceSuccessful = true; CurItem.SubItems[1].Text = " " + Date.ToString(); } savedFile.Close();

    //если не получилось сохранить обычным путем сохраняем необычным if (!inPlaceSuccessful) { string newExtension = "output"; string outputFileName = ""; // ChangeExtension(filename, "output"); int dotIndex = filename.LastIndexOf('.'); if (dotIndex == -1) outputFileName = filename; else outputFileName = filename.Substring(0, dotIndex + 1) + newExtension; WriteCopyOfPictureUsingWic(filename, outputFileName); System.IO.File.Delete(filename); System.IO.File.Move(outputFileName, filename); }

    }

    private void WriteCopyOfPictureUsingWic(string originalFileName, string outputFileName)
    {
    bool tryOneLastMethod = false;
       using (System.IO.Stream originalFile = new System.IO.FileStream(originalFileName, System.IO.FileMode.Open, System.IO.FileAccess.Read, System.IO.FileShare.Read))
       {
        System.Windows.Media.Imaging.BitmapCreateOptions createOptions = System.Windows.Media.Imaging.BitmapCreateOptions.PreservePixelFormat | System.Windows.Media.Imaging.BitmapCreateOptions.IgnoreColorProfile;
          System.Windows.Media.Imaging.BitmapDecoder original = System.Windows.Media.Imaging.BitmapDecoder.Create(originalFile, createOptions, System.Windows.Media.Imaging.BitmapCacheOption.None);
          System.Windows.Media.Imaging.JpegBitmapEncoder output = new System.Windows.Media.Imaging.JpegBitmapEncoder();

          if (original.Frames[0] != null && original.Frames[0].Metadata != null)
          {
          System.Windows.Media.Imaging.BitmapMetadata bitmapMetadata = original.Frames[0].Metadata.Clone() as System.Windows.Media.Imaging.BitmapMetadata;
             bitmapMetadata.SetQuery("/app1/ifd/PaddingSchema:Padding", METADATA_PADDING_IN_BYTES);
             bitmapMetadata.SetQuery("/app1/ifd/exif/PaddingSchema:Padding", METADATA_PADDING_IN_BYTES);
             bitmapMetadata.SetQuery("/xmp/PaddingSchema:Padding", METADATA_PADDING_IN_BYTES);

             bitmapMetadata.DateTaken = Date.ToString("M/d/yyyy HH:mm:ss");
             bitmapMetadata.SetQuery(DATE_TAKEN_QUERY, Date.ToString("yyyy:MM:dd HH:mm:ss"));
             bitmapMetadata.SetQuery(DIGITIZED_DATE_QUERY, Date.ToString("yyyy:MM:dd HH:mm:ss"));
             bitmapMetadata.SetQuery(ORIGINAL_DATE_QUERY, Date.ToString("yyyy:MM:dd HH:mm:ss"));

             output.Frames.Add(System.Windows.Media.Imaging.BitmapFrame.Create(original.Frames[0], original.Frames[0].Thumbnail, bitmapMetadata, original.Frames[0].ColorContexts));
          }

          try
          {
          using (System.IO.Stream outputFile = System.IO.File.Open(outputFileName, System.IO.FileMode.Create, System.IO.FileAccess.ReadWrite))
             {
              output.Save(outputFile);
             }
          }
          catch (NotSupportedException e)
          {
          System.Diagnostics.Debug.Print(e.Message);
             output = new System.Windows.Media.Imaging.JpegBitmapEncoder();
             output.Frames.Add(System.Windows.Media.Imaging.BitmapFrame.Create(original.Frames[0], original.Frames[0].Thumbnail, original.Metadata, original.Frames[0].ColorContexts));
             using (System.IO.Stream outputFile = System.IO.File.Open(outputFileName, System.IO.FileMode.Create, System.IO.FileAccess.ReadWrite))
             {
              output.Save(outputFile);
             }
             tryOneLastMethod = true;
          }
       }

       if (tryOneLastMethod)
       {
        System.IO.File.Move(outputFileName, outputFileName + "tmp");
          using (System.IO.Stream recentlyOutputFile = new System.IO.FileStream(outputFileName + "tmp", System.IO.FileMode.Open, System.IO.FileAccess.Read, System.IO.FileShare.Read))
          {
          System.Windows.Media.Imaging.BitmapCreateOptions createOptions = System.Windows.Media.Imaging.BitmapCreateOptions.PreservePixelFormat | System.Windows.Media.Imaging.BitmapCreateOptions.IgnoreColorProfile;
             System.Windows.Media.Imaging.BitmapDecoder original = System.Windows.Media.Imaging.BitmapDecoder.Create(recentlyOutputFile, createOptions, System.Windows.Media.Imaging.BitmapCacheOption.None);
             System.Windows.Media.Imaging.JpegBitmapEncoder output = new System.Windows.Media.Imaging.JpegBitmapEncoder();
             if (original.Frames[0] != null && original.Frames[0].Metadata != null)
             {
              System.Windows.Media.Imaging.BitmapMetadata bitmapMetadata = original.Frames[0].Metadata.Clone() as System.Windows.Media.Imaging.BitmapMetadata;
                bitmapMetadata.SetQuery("/app1/ifd/PaddingSchema:Padding", METADATA_PADDING_IN_BYTES);
                bitmapMetadata.SetQuery("/app1/ifd/exif/PaddingSchema:Padding", METADATA_PADDING_IN_BYTES);
                bitmapMetadata.SetQuery("/xmp/PaddingSchema:Padding", METADATA_PADDING_IN_BYTES);

                bitmapMetadata.DateTaken = Date.ToString("M/d/yyyy HH:mm:ss");
                bitmapMetadata.SetQuery(DATE_TAKEN_QUERY, Date.ToString("yyyy:MM:dd HH:mm:ss"));
                bitmapMetadata.SetQuery(DIGITIZED_DATE_QUERY, Date.ToString("yyyy:MM:dd HH:mm:ss"));
                bitmapMetadata.SetQuery(ORIGINAL_DATE_QUERY, Date.ToString("yyyy:MM:dd HH:mm:ss"));

                output.Frames.Add(System.Windows.Media.Imaging.BitmapFrame.Create(original.Frames[0], original.Frames[0].Thumbnail, bitmapMetadata, original.Frames[0].ColorContexts));
             }

             using (System.IO.Stream outputFile = System.IO.File.Open(outputFileName, System.IO.FileMode.Create, System.IO.FileAccess.ReadWrite))
             {
              output.Save(outputFile);
             }
          }
          System.IO.File.Delete(outputFileName + "tmp");
       }
    }


    • Помечено в качестве ответа Dobrii 30 мая 2013 г. 7:09
  • Здравствуйте,

    Можете попробовать как здесь:

    How to Edit Meta Data Inside JPG Files with C#


    Если вам помог чей-либо ответ, пожалуйста, не забывайте жать на кнопку "Предложить как ответ" или "Проголосовать за полезное сообщение"

    • Помечено в качестве ответа Dobrii 30 мая 2013 г. 7:09
    Модератор

Все ответы

  • Здравствуйте,

    Можете попробовать как здесь:

    How to Edit Meta Data Inside JPG Files with C#


    Если вам помог чей-либо ответ, пожалуйста, не забывайте жать на кнопку "Предложить как ответ" или "Проголосовать за полезное сообщение"

    • Помечено в качестве ответа Dobrii 30 мая 2013 г. 7:09
    Модератор
  • using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.IO;
    using System.Windows.Media.Imaging;
    
    namespace ByteProgram.DateToEXIF {
        
        class ReadFiles {
    
            static void Main(string[] args) {
                string curDir;
                curDir = Directory.GetCurrentDirectory();
                IEnumerable<string> jpgFilesInDir;
               
                if (args.Length > 0)
                {
                    if(args[0] == "/?") {
                        Console.WriteLine("Изменение даты последней записи в файл на дату съемки");
                        Console.WriteLine("Использование: ");
                        Console.WriteLine("     запуск без параметров - изменение в текущей папке");
                        Console.WriteLine("     <папка> - изменение в указанной папке");
                        return;
                    }
                    if (Directory.Exists(args[0]))
                    {
                        jpgFilesInDir = Directory.EnumerateFiles(args[0], "*.jpg");  //получаем список файлов в указаной директории
                    }
                    else
                    {
                        Console.WriteLine("Указанного пути не сущестует");
                        return;
                    }
                }
                else
                {
                    jpgFilesInDir = Directory.EnumerateFiles(curDir, "*.jpg");   //получаем список файлов в текущей директории
                }
                FileInfo fInf;
                foreach (string currentFile in jpgFilesInDir)   //проходим по всем файлам
                {
                    fInf = new FileInfo(currentFile);
                    Console.WriteLine("Обрабатываем файл: {0}", fInf.Name);
                    ReadExifInfo rex = new ReadExifInfo(currentFile);
                    try
                    {
                        if (rex.CreateTime.Date.Year > 1980)
                        {
                            Console.WriteLine("Дата съемки: {0}", rex.CreateTime);
                            if (fInf.LastWriteTime != rex.CreateTime)
                            {
                                Console.WriteLine("Устанавливаем новое время редактирования файла.");
                                fInf.LastWriteTime = rex.CreateTime;
                            }
                            else
                            {
                                Console.WriteLine("Даты совпадают, изменение не требуется.");
                            }
                        }
                        else
                        {
                            Console.WriteLine("Некорректная дата съемки.");
                        }
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine(e.Message);
                    }
                }  
              
            }
        }
    
        class ReadExifInfo {    //для чтения EXIF информации из файла
            private DateTime creationTime;
            private FileStream Foto;
            private BitmapMetadata TmpImgEXIF;
            
            public ReadExifInfo (string fileName) { //конструктор
                try
                {
                    Foto = File.Open(fileName, FileMode.Open, FileAccess.Read); // открыли файл по адресу fileName для чтения
                }
                catch (Exception)
                {
                    Console.WriteLine("Невозможно открыть файл");
                }
                try
                {
                    JpegBitmapDecoder decoder = new JpegBitmapDecoder(Foto, BitmapCreateOptions.IgnoreColorProfile, BitmapCacheOption.Default); //"распаковали" снимок и создали объект decoder
                    TmpImgEXIF = (BitmapMetadata)decoder.Frames[0].Metadata.Clone(); //считали и сохранили метаданные
                    creationTime = Convert.ToDateTime(TmpImgEXIF.DateTaken);    //в переменную дату съемки
                    Foto.Close();
                }
                catch (Exception e)
                {
                    Console.WriteLine(e.Message);
                    Console.WriteLine("Невозможно прочитать EXIF информацию.");
                    Foto.Close();
                }
            }
    
            public DateTime CreateTime {    //возвращаем дату и время съемки
                get { return creationTime;  }
            }
        }
    }

  • private const string DATE_TAKEN_QUERY = "/app1/ifd/{ushort=306}";
    private const string ORIGINAL_DATE_QUERY = "/app1/ifd/exif/{ushort=36867}";
    private const string DIGITIZED_DATE_QUERY = "/app1/ifd/exif/{ushort=36868}";
    private const string LATITUDE_QUERY = "/app1/ifd/gps/subifd:{ulong=2}";
    private const string LONGITUDE_QUERY = "/app1/ifd/gps/subifd:{ulong=4}";
    private const string NORTH_OR_SOUTH_QUERY = "/app1/ifd/gps/subifd:{char=1}";
    private const string EAST_OR_WEST_QUERY = "/app1/ifd/gps/subifd:{char=3}";
    private const string GPS_VERSION_QUERY = "/app1/ifd/gps/";
    private const string IPTC_KEYWORDS_QUERY = "/app13/irb/8bimiptc/iptc/keywords";

    using (System.IO.Stream savedFile = System.IO.File.Open(filename, System.IO.FileMode.Open, System.IO.FileAccess.ReadWrite)) { bool inPlaceSuccessful = false; System.Windows.Media.Imaging.BitmapDecoder output = System.Windows.Media.Imaging.BitmapDecoder.Create(savedFile, System.Windows.Media.Imaging.BitmapCreateOptions.None, System.Windows.Media.Imaging.BitmapCacheOption.Default); System.Windows.Media.Imaging.InPlaceBitmapMetadataWriter bitmapMetadata = output.Frames[0].CreateInPlaceBitmapMetadataWriter(); if (!bitmapMetadata.TrySave()) // проверяем можно ли сохранить изменения { bitmapMetadata.DateTaken = Date.ToString("M/d/yyyy HH:mm:ss"); bitmapMetadata.SetQuery(DATE_TAKEN_QUERY, Date.ToString("yyyy:MM:dd HH:mm:ss")); bitmapMetadata.SetQuery(DIGITIZED_DATE_QUERY, Date.ToString("yyyy:MM:dd HH:mm:ss")); bitmapMetadata.SetQuery(ORIGINAL_DATE_QUERY, Date.ToString("yyyy:MM:dd HH:mm:ss")); inPlaceSuccessful = true; CurItem.SubItems[1].Text = " " + Date.ToString(); } savedFile.Close();

    //если не получилось сохранить обычным путем сохраняем необычным if (!inPlaceSuccessful) { string newExtension = "output"; string outputFileName = ""; // ChangeExtension(filename, "output"); int dotIndex = filename.LastIndexOf('.'); if (dotIndex == -1) outputFileName = filename; else outputFileName = filename.Substring(0, dotIndex + 1) + newExtension; WriteCopyOfPictureUsingWic(filename, outputFileName); System.IO.File.Delete(filename); System.IO.File.Move(outputFileName, filename); }

    }

    private void WriteCopyOfPictureUsingWic(string originalFileName, string outputFileName)
    {
    bool tryOneLastMethod = false;
       using (System.IO.Stream originalFile = new System.IO.FileStream(originalFileName, System.IO.FileMode.Open, System.IO.FileAccess.Read, System.IO.FileShare.Read))
       {
        System.Windows.Media.Imaging.BitmapCreateOptions createOptions = System.Windows.Media.Imaging.BitmapCreateOptions.PreservePixelFormat | System.Windows.Media.Imaging.BitmapCreateOptions.IgnoreColorProfile;
          System.Windows.Media.Imaging.BitmapDecoder original = System.Windows.Media.Imaging.BitmapDecoder.Create(originalFile, createOptions, System.Windows.Media.Imaging.BitmapCacheOption.None);
          System.Windows.Media.Imaging.JpegBitmapEncoder output = new System.Windows.Media.Imaging.JpegBitmapEncoder();

          if (original.Frames[0] != null && original.Frames[0].Metadata != null)
          {
          System.Windows.Media.Imaging.BitmapMetadata bitmapMetadata = original.Frames[0].Metadata.Clone() as System.Windows.Media.Imaging.BitmapMetadata;
             bitmapMetadata.SetQuery("/app1/ifd/PaddingSchema:Padding", METADATA_PADDING_IN_BYTES);
             bitmapMetadata.SetQuery("/app1/ifd/exif/PaddingSchema:Padding", METADATA_PADDING_IN_BYTES);
             bitmapMetadata.SetQuery("/xmp/PaddingSchema:Padding", METADATA_PADDING_IN_BYTES);

             bitmapMetadata.DateTaken = Date.ToString("M/d/yyyy HH:mm:ss");
             bitmapMetadata.SetQuery(DATE_TAKEN_QUERY, Date.ToString("yyyy:MM:dd HH:mm:ss"));
             bitmapMetadata.SetQuery(DIGITIZED_DATE_QUERY, Date.ToString("yyyy:MM:dd HH:mm:ss"));
             bitmapMetadata.SetQuery(ORIGINAL_DATE_QUERY, Date.ToString("yyyy:MM:dd HH:mm:ss"));

             output.Frames.Add(System.Windows.Media.Imaging.BitmapFrame.Create(original.Frames[0], original.Frames[0].Thumbnail, bitmapMetadata, original.Frames[0].ColorContexts));
          }

          try
          {
          using (System.IO.Stream outputFile = System.IO.File.Open(outputFileName, System.IO.FileMode.Create, System.IO.FileAccess.ReadWrite))
             {
              output.Save(outputFile);
             }
          }
          catch (NotSupportedException e)
          {
          System.Diagnostics.Debug.Print(e.Message);
             output = new System.Windows.Media.Imaging.JpegBitmapEncoder();
             output.Frames.Add(System.Windows.Media.Imaging.BitmapFrame.Create(original.Frames[0], original.Frames[0].Thumbnail, original.Metadata, original.Frames[0].ColorContexts));
             using (System.IO.Stream outputFile = System.IO.File.Open(outputFileName, System.IO.FileMode.Create, System.IO.FileAccess.ReadWrite))
             {
              output.Save(outputFile);
             }
             tryOneLastMethod = true;
          }
       }

       if (tryOneLastMethod)
       {
        System.IO.File.Move(outputFileName, outputFileName + "tmp");
          using (System.IO.Stream recentlyOutputFile = new System.IO.FileStream(outputFileName + "tmp", System.IO.FileMode.Open, System.IO.FileAccess.Read, System.IO.FileShare.Read))
          {
          System.Windows.Media.Imaging.BitmapCreateOptions createOptions = System.Windows.Media.Imaging.BitmapCreateOptions.PreservePixelFormat | System.Windows.Media.Imaging.BitmapCreateOptions.IgnoreColorProfile;
             System.Windows.Media.Imaging.BitmapDecoder original = System.Windows.Media.Imaging.BitmapDecoder.Create(recentlyOutputFile, createOptions, System.Windows.Media.Imaging.BitmapCacheOption.None);
             System.Windows.Media.Imaging.JpegBitmapEncoder output = new System.Windows.Media.Imaging.JpegBitmapEncoder();
             if (original.Frames[0] != null && original.Frames[0].Metadata != null)
             {
              System.Windows.Media.Imaging.BitmapMetadata bitmapMetadata = original.Frames[0].Metadata.Clone() as System.Windows.Media.Imaging.BitmapMetadata;
                bitmapMetadata.SetQuery("/app1/ifd/PaddingSchema:Padding", METADATA_PADDING_IN_BYTES);
                bitmapMetadata.SetQuery("/app1/ifd/exif/PaddingSchema:Padding", METADATA_PADDING_IN_BYTES);
                bitmapMetadata.SetQuery("/xmp/PaddingSchema:Padding", METADATA_PADDING_IN_BYTES);

                bitmapMetadata.DateTaken = Date.ToString("M/d/yyyy HH:mm:ss");
                bitmapMetadata.SetQuery(DATE_TAKEN_QUERY, Date.ToString("yyyy:MM:dd HH:mm:ss"));
                bitmapMetadata.SetQuery(DIGITIZED_DATE_QUERY, Date.ToString("yyyy:MM:dd HH:mm:ss"));
                bitmapMetadata.SetQuery(ORIGINAL_DATE_QUERY, Date.ToString("yyyy:MM:dd HH:mm:ss"));

                output.Frames.Add(System.Windows.Media.Imaging.BitmapFrame.Create(original.Frames[0], original.Frames[0].Thumbnail, bitmapMetadata, original.Frames[0].ColorContexts));
             }

             using (System.IO.Stream outputFile = System.IO.File.Open(outputFileName, System.IO.FileMode.Create, System.IO.FileAccess.ReadWrite))
             {
              output.Save(outputFile);
             }
          }
          System.IO.File.Delete(outputFileName + "tmp");
       }
    }


    • Помечено в качестве ответа Dobrii 30 мая 2013 г. 7:09
  • Спасибо, что предоставили свое решение, будет в помощ другим.


    Если вам помог чей-либо ответ, пожалуйста, не забывайте жать на кнопку "Предложить как ответ" или "Проголосовать за полезное сообщение"

    Модератор