0

My TelegramBot receives an image and stores it somewhere, the name of the created file is the date and time the image was taken (f.e. 2018-07-13_13-18-55.jpg)

I get this information from the metadata of the image with the following code:

 private static string Date_taken(Image image, MessageEventArgs e, int messageId)
    {
        try
        {
            var propItem = image.GetPropertyItem(36867);
            var originalDateString = Encoding.UTF8.GetString(propItem.Value);
            originalDateString = originalDateString.Remove(originalDateString.Length - 1);
            return originalDateString.Replace(":", "-").Replace(" ", "_");
        }
        catch
        {
            Trace.WriteLine(NowLog + " " + MessageIDformat(messageId) + " " + Resources.TelegramBot_Date_taken_no_capturetime + " " + e.Message.Chat.Username);
            return DateTime.Today.ToString("yyyy-MM-dd") + "_" + DateTime.Now.ToString("HH-mm-ss", System.Globalization.DateTimeFormatInfo.InvariantInfo) + "_noCaptureTime";
        }
    }

The picture is named correctly, BUT the metadata is somehow lost in this process (only date and time when the image was taken).

The only thing I do with the picture in addition to the above code is saving it:

private static string Save_image(MessageEventArgs e, Image image, int messageId)
    {
        Bitmap finalImage;
        var hasCompression = HasCompression(e.Message.Chat.Username);
        var res = (double)image.Width / image.Height;
        int width = image.Width,
            height = image.Height;
        var dateTaken = Date_taken(image, e, messageId);

        if(res <= 1)
        {
            //Portrait
            height = hasCompression ? MaxLen : height;
            width = hasCompression ? Convert.ToInt16(height * res): width;
        }
        else
        {
            //Landscape
            width = hasCompression ? MaxLen : width;
            height = hasCompression ? Convert.ToInt16(width / res): height;
        }

        if (image.Width > width && image.Height > height)
            finalImage = ResizeImg(image, width, height);
        else
            finalImage = ResizeImg(image, image.Width, image.Height);

        var jpgEncoder = GetEncoder(ImageFormat.Jpeg);
        var myEncoder = System.Drawing.Imaging.Encoder.Quality;
        var encoder = new EncoderParameters(1);
        var encoderParameter = new EncoderParameter(myEncoder, hasCompression ? EncodeQ : 93L);
        encoder.Param[0] = encoderParameter;

        if (!File.Exists(PathPhotos + e.Message.Chat.Username + @"\" + dateTaken + ".jpg"))
        {
            finalImage.Save(PathPhotos + e.Message.Chat.Username + @"\" + dateTaken + ".jpg", jpgEncoder, encoder);
            return dateTaken + ".jpg";
        }
        else if (!File.Exists(PathPhotos + e.Message.Chat.Username + @"\" + dateTaken + " (2)" + ".jpg"))
        {
            finalImage.Save(PathPhotos + e.Message.Chat.Username + @"\" + dateTaken + " (2)" + ".jpg", jpgEncoder, encoder);
            return dateTaken + " (2)" + ".jpg";
        }
        else
        {
            var path = PathPhotos + e.Message.Chat.Username + @"\";
            var dir = new DirectoryInfo(path);
            var number = 0;

            foreach (var file in dir.GetFiles("*" + ".jpg"))
            {
                int test;
                try
                {
                    var pFrom = file.ToString().IndexOf("(") + "(".Length;
                    var pTo = file.ToString().LastIndexOf(")");

                    test = Convert.ToInt16(file.ToString().Substring(pFrom, pTo - pFrom));
                }
                catch (Exception)
                {
                    test = 0;
                }

                if (number < test)
                    number = test;
            }
            number++;
            finalImage.Save(PathPhotos + e.Message.Chat.Username + @"\" + dateTaken + " (" + number + ")" + ".jpg", jpgEncoder, encoder);
            return dateTaken + " (" + number + ")" + ".jpg";
        }

Could it be that the jpg encoder deletes the metadata?

TMaddox
  • 77
  • 1
  • 11
  • Get an EXIF reader tool and check the original and saved file. – Anton Tykhyy Jul 13 '18 at 12:01
  • @AntonTykhyy I can use windows for that, and I already did that. The Problem is, as stated in my post, that the original picture has the data and successfully accesses it (otherwise it couldn´t name the picture correctly), and after saving the metadata is lost. – TMaddox Jul 13 '18 at 12:05
  • 1
    Then why ask whether it is lost or not? I suspect you have to add metadata to your new image with [`Image.SetPropertyItem()`](https://learn.microsoft.com/en-us/dotnet/api/system.drawing.image.setpropertyitem), it won't just magically appear in the resized image. – Anton Tykhyy Jul 13 '18 at 14:17
  • `finalimg` isn't your original image; it's the result of the `ResizeImg` function... so I guess that's the one that may not preserve your exif data. – Nyerguds Jul 17 '18 at 08:24

1 Answers1

1

With the help of @Anton Tykhyy comment, I could solve this.

if(image != 0)
{
    finalImage.SetPropertyItem(GetDateTakenFromImage(image));
}

GetDateTakenFromImage method:

public static PropertyItem GetDateTakenFromImage(Image image)
    {
        try
        {
            return image.GetPropertyItem(36867);
        }
        catch
        {
            return null;
        }
    }
TMaddox
  • 77
  • 1
  • 11