private void SetPropertyItemString(System.Drawing.Image image, PropertyTagId id, String value) { byte[] buffer = Encoding.Unicode.GetBytes(value); PropertyItem propItem = image.GetPropertyItem((int)id); propItem.Len = buffer.Length; propItem.Value = buffer; image.SetPropertyItem(propItem); }
public static void FixExifDateTime(string photoPath, TimeSpan timeSpan) { var files = Directory.GetFiles(photoPath); //获取所有照片路径 IFormatProvider culture = new CultureInfo("zh-CN", true); foreach (var file in files) { //替代System.Drawing.Image.FromFile(file); System.Drawing.Image image = GetImage(file); //获取Exif的DateTimeOriginal属性(36867) PropertyItem pi = image.GetPropertyItem(36867); //(int)ExifTags.DateTimeOriginal //转为时间文本 string oldTime = Encoding.ASCII.GetString(pi.Value); oldTime = oldTime.Replace("\0", ""); Debug.WriteLine(file + " " + oldTime); //时间文本格式化为DateTime DateTime time = DateTime.ParseExact(oldTime, "yyyy:MM:dd HH:mm:ss", culture); //由于是接着ExifToolGui没有改完的目录,所以只转换EXIF记录为timeFalse年份的, //跨年的话要另外处理,因为我这里不跨年,所以简单点 //得到正确的时间 DateTime newTime = time + timeSpan; //转换为EXIF存储的时间格式 string newTimeString = newTime.ToString("yyyy:MM:dd HH:mm:ss"); pi.Value = Encoding.ASCII.GetBytes(newTimeString + "\0"); //修改DateTimeOriginal属性和其他的时间属性 image.SetPropertyItem(pi); pi.Id = 306; // (int)ExifTags.DateTime; //306 image.SetPropertyItem(pi); pi.Id = 36868; //(int)ExifTags.DateTimeDigitized; //36868 image.SetPropertyItem(pi); //存回文件 image.Save(file); image.Dispose(); } }
private static void SetImageProperty(Image image, int propertyId, byte[] value) { var prop = (PropertyItem)FormatterServices.GetUninitializedObject(typeof(PropertyItem)); prop.Id = propertyId; prop.Value = value; prop.Len = prop.Value.Length; prop.Type = 1; image.SetPropertyItem(prop); }
private void WriteLatLon(double d, bool fLatitude) { string sRef = fLatitude ? ((d < 0) ? "S" : "N") : ((d < 0) ? "W" : "E"); DMSAngle dmsa = new DMSAngle(d); FractionStruct[] f = new FractionStruct[3]; f[0] = (FractionStruct) new Fraction(dmsa.Degrees); f[1] = (FractionStruct) new Fraction(dmsa.Minutes); f[2] = (FractionStruct) new Fraction(dmsa.Seconds, 5); // Write reference PropertyItem pi = _image.PropertyItems[0]; // use an existing property pi.Type = (short)PropertyTagType.ASCII; pi.Id = (int)(fLatitude ? PropertyTagId.GpsLatitudeRef : PropertyTagId.GpsLongitudeRef); pi.Len = Encoding.ASCII.GetByteCount(sRef) + 1; pi.Value = new byte[pi.Len]; byte[] rgbSz = Encoding.ASCII.GetBytes(sRef); rgbSz.CopyTo(pi.Value, 0); pi.Value[pi.Len - 1] = 0; _image.SetPropertyItem(pi); // Now write the value pi = _image.PropertyItems[0]; pi.Type = (short)PropertyTagType.Rational; pi.Id = (int)(fLatitude ? PropertyTagId.GpsLatitude : PropertyTagId.GpsLongitude); pi.Len = Marshal.SizeOf(f[0]) * f.Length; pi.Value = new byte[pi.Len]; IntPtr ptr = Marshal.AllocHGlobal(pi.Len); for (int i = 0; i < f.Length; i++) { Marshal.StructureToPtr(f[i], new IntPtr(ptr.ToInt64() + i * Marshal.SizeOf(f[0])), true); } Marshal.Copy(ptr, pi.Value, 0, pi.Len); Marshal.FreeHGlobal(ptr); _image.SetPropertyItem(pi); }
private void CopyPropertyItem(System.Drawing.Image source, System.Drawing.Image destination, PropertyTagId id) { PropertyItem propItem = source.GetPropertyItem((int)id); destination.SetPropertyItem(propItem); /* * switch (propItem.Type) * { * case 1: //Specifies that Value is an array of bytes. * destination.SetPropertyItem(propItem); * break; * * case 2: //Specifies that Value is a null-terminated ASCII string. If you set the type data member to ASCII type, you should set the Len property to the length of the string including the null terminator. For example, the string "Hello" would have a length of 6. * throw new NotImplementedException(); * break; * * case 3: //Specifies that Value is an array of unsigned short (16-bit) integers. * throw new NotImplementedException(); * break; * * case 4: //Specifies that Value is an array of unsigned long (32-bit) integers. * throw new NotImplementedException(); * break; * * case 5: //Specifies that Value data member is an array of pairs of unsigned long integers. Each pair represents a fraction; the first integer is the numerator and the second integer is the denominator. * throw new NotImplementedException(); * break; * * case 6: //Specifies that Value is an array of bytes that can hold values of any data type. * throw new NotImplementedException(); * break; * * case 7: //Specifies that Value is an array of signed long (32-bit) integers. * throw new NotImplementedException(); * break; * * case 10: //Specifies that Value is an array of pairs of signed long integers. Each pair represents a fraction; the first integer is the numerator and the second integer is the denominator. * throw new NotImplementedException(); * break; * * }*/ }
private void LoadImage(string filename) { FullScreenImage.RenderTransform = null; FullScreenImage.Visibility = Visibility.Visible; FullScreenMedia.Visibility = Visibility.Collapsed; try { using ( var imgStream = File.Open(filename, FileMode.Open, FileAccess.Read, FileShare.Delete | FileShare.ReadWrite)) { using (Image imgForExif = Image.FromStream(imgStream, false, false)) { // Check to see if image display needs to be rotated per EXIF Orientation parameter (274) or user R key input if (Array.IndexOf(imgForExif.PropertyIdList, 274) > -1) { PropertyItem orientation = imgForExif.GetPropertyItem(274); var fType = GetRotateFlipTypeByExifOrientationData((int)orientation.Value[0]); // Check to see if user requested rotation (R key) if (imageRotationAngle == 90) { orientation.Value = BitConverter.GetBytes((int)GetNextRotationOrientation((int)orientation.Value[0])); // Set EXIF tag property to new orientation imgForExif.SetPropertyItem(orientation); // update RotateFlipType accordingly fType = GetRotateFlipTypeByExifOrientationData((int)orientation.Value[0]); //Rotate90(filename); imgForExif.SetPropertyItem(imgForExif.PropertyItems[0]); // Save rotation to file imgForExif.RotateFlip(System.Drawing.RotateFlipType.Rotate90FlipNone); switch (Path.GetExtension(filename).ToLower()) { case ".jpg": imgForExif.Save(filename, ImageFormat.Jpeg); break; case ".png": imgForExif.Save(filename, ImageFormat.Png); break; case ".bmp": imgForExif.Save(filename, ImageFormat.Bmp); break; case ".gif": imgForExif.Save(filename, ImageFormat.Gif); break; } } /* * // Rotate display of image accordingly * fType = GetRotateFlipTypeByExifOrientationData((int)orientation.Value[0]); * if (fType != System.Drawing.RotateFlipType.RotateNoneFlipNone) * { * imgForExif.RotateFlip(fType); * } */ // Get rotation angle accordingly imageRotationAngle = GetBitmapRotationAngleByRotationFlipType(fType); } } var img = new BitmapImage(); img.BeginInit(); img.CacheOption = BitmapCacheOption.OnLoad; //img.UriSource = new Uri(filename); imgStream.Seek(0, SeekOrigin.Begin); // seek stream to beginning img.StreamSource = imgStream; // load image from stream instead of file img.EndInit(); // Rotate Image if necessary TransformedBitmap transformBmp = new TransformedBitmap(); transformBmp.BeginInit(); transformBmp.Source = img; RotateTransform transform = new RotateTransform(imageRotationAngle); transformBmp.Transform = transform; transformBmp.EndInit(); FullScreenImage.Source = transformBmp; // Initialize rotation variable for next image imageRotationAngle = 0; //FullScreenImage.Source = img; imageTimer.Start(); //********* NEW EXIF CODE ************** imgStream.Seek(0, SeekOrigin.Begin); if (Path.GetExtension(filename).ToLower() == ".jpg") // load exif only for jpg { StringBuilder info = new StringBuilder(); info.AppendLine(filename + "\n" + (int)img.Width + "x" + (int)img.Height); var decoder = new JpegBitmapDecoder(imgStream, BitmapCreateOptions.IgnoreColorProfile | BitmapCreateOptions.IgnoreImageCache | BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.None); var bitmapFrame = decoder.Frames[0]; if (bitmapFrame != null) { BitmapMetadata metaData = (BitmapMetadata)bitmapFrame.Metadata.Clone(); if (metaData != null) { if (!String.IsNullOrWhiteSpace(metaData.DateTaken)) { info.AppendLine("Date taken: " + metaData.DateTaken); } if (!String.IsNullOrWhiteSpace(metaData.Title)) { info.AppendLine("Title: " + metaData.Title); } if (!String.IsNullOrWhiteSpace(metaData.Subject)) { info.AppendLine("Subject: " + metaData.Subject); } if (!String.IsNullOrWhiteSpace(metaData.Comment)) { info.AppendLine("User comment: " + metaData.Comment); } } } Overlay.Text = info.ToString(); } else { Overlay.Text = filename + "\n" + (int)img.Width + "x" + (int)img.Height; } } } catch { FullScreenImage.Source = null; ShowError("Can not load " + filename + " ! Screensaver paused, press P to unpause."); } }