图像中的元数据在读取时被删除?
Metadata from image is deleted on reading it?
我的 TelegramBot 收到一张图片并将其存储在某个地方,创建的文件的名称是拍摄图片的日期和时间 (f.e。2018-07-13_13-18-55.jpg)
我使用以下代码从图像的元数据中获取此信息:
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";
}
}
图片命名正确,但元数据在此过程中以某种方式丢失(仅拍摄图片的日期和时间)。
除了上面的代码,我唯一对图片做的就是保存它:
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";
}
会不会是jpg编码器删除了元数据?
在@Anton Tykhyy 评论的帮助下,我可以解决这个问题。
if(image != 0)
{
finalImage.SetPropertyItem(GetDateTakenFromImage(image));
}
GetDateTakenFromImage 方法:
public static PropertyItem GetDateTakenFromImage(Image image)
{
try
{
return image.GetPropertyItem(36867);
}
catch
{
return null;
}
}
我的 TelegramBot 收到一张图片并将其存储在某个地方,创建的文件的名称是拍摄图片的日期和时间 (f.e。2018-07-13_13-18-55.jpg)
我使用以下代码从图像的元数据中获取此信息:
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";
}
}
图片命名正确,但元数据在此过程中以某种方式丢失(仅拍摄图片的日期和时间)。
除了上面的代码,我唯一对图片做的就是保存它:
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";
}
会不会是jpg编码器删除了元数据?
在@Anton Tykhyy 评论的帮助下,我可以解决这个问题。
if(image != 0)
{
finalImage.SetPropertyItem(GetDateTakenFromImage(image));
}
GetDateTakenFromImage 方法:
public static PropertyItem GetDateTakenFromImage(Image image)
{
try
{
return image.GetPropertyItem(36867);
}
catch
{
return null;
}
}