Ответ 1
У меня тоже была проблема, поэтому позвольте мне поделиться моей оценкой ситуации здесь:
Google, похоже, отображает отображаемую метаинформацию из тегов Exif изображения. Хотя установка тегов Exif представляется возможной при просмотре API.net(я даже декомпилировал сборки Google, чтобы убедиться, что все правильно), Google просто не добавляет их в изображение при выпуске обновления.
Итак, мой подход заключается в загрузке всех изображений, изменении их информации Exif и их повторной загрузке (например, предложенный nemesv). К сожалению, Google блокирует все загруженные файлы своих тегов Exif (спасибо large G!) И заменяет их искусственными (например, имя приложения "Google" ) и нулевые значения (время создания = нуль). Генерация. Exif-информация с нуля в .net в лучшем случае хакерская (нужно принудительно построить экземпляры System.Drawing.Imaging.PropertyItem [имеет встроенный конструктор, можно сделать] и правильно их параметризовать). Но, поскольку я сделал что-то вроде этого (вывел Exif-информацию из существующего pic, обновил pic и повторно добавил Exif к новому рис.) В модуль обработки изображений приложения на моей основной работе, я считаю этот подход выполнимым.
Вот несколько примеров кода концепции для вас. Он не проходит полностью (полное решение должно читать даты существующих записей picasa и кэшировать их в списке, чтобы повторно использовать их на загруженных изображениях), но он охватывает сложные элементы.
private void button1_Click(object sender, EventArgs e)
{
var service = new PicasaService("exampleCo-exampleApp-1");
service.setUserCredentials("[email protected]", "-secret-");
AlbumQuery query = new AlbumQuery(PicasaQuery.CreatePicasaUri("default"));
PicasaFeed feed = service.Query(query);
var entry = (PicasaEntry)feed.Entries.SingleOrDefault(f => f.Title.Text == "Testalbum");
var ac = new AlbumAccessor(entry);
var photoQuery = new PhotoQuery(PicasaQuery.CreatePicasaUri("default", ac.Id));
PicasaFeed photoFeed = service.Query(photoQuery);
DirectoryInfo srcdir = Directory.CreateDirectory("C:\\Temp\\Testalbum");
DownloadAllPhotos("C:\\Temp\\Testalbum", photoFeed.Entries);
foreach (PicasaEntry oldentry in photoFeed.Entries)
{
oldentry.Delete();
}
DirectoryInfo tgtdir = Directory.CreateDirectory("C:\\Temp\\Converted");
foreach (FileInfo imagefile in srcdir.EnumerateFiles())
{
Image img = Image.FromFile(imagefile.FullName);
PropertyItem PiDtOrig = null;
try
{
PiDtOrig = img.GetPropertyItem(0x9003); // id 0x9003 is "DateTimeOriginal"
}
catch (System.ArgumentException ex) // this exception is thrown when PropertyItem does not exist
{
PiDtOrig = NewPropertyItem();
PiDtOrig.Id = 0x9003;
PiDtOrig.Type = 7;
PiDtOrig.Len = 4;
}
PiDtOrig.Value = BitConverter.GetBytes(DateTimeToInt(DateTime.Now));
img.SetPropertyItem(PiDtOrig);
string ConvImgName = tgtdir.FullName + "\\" + imagefile.Name;
img.Save(ConvImgName);
//ExifTagCollection exif = new ExifTagCollection(img);
//Debug.WriteLine(exif);
Uri postUri = new Uri(PicasaQuery.CreatePicasaUri("[email protected]", ac.Id));
FileStream fileStream = imagefile.OpenRead();
PicasaEntry newentry = (PicasaEntry)service.Insert(postUri, fileStream, "image/jpeg", ConvImgName);
fileStream.Close();
fileStream.Dispose();
}
}
private PropertyItem NewPropertyItem()
{
Type t = typeof (PropertyItem);
ConstructorInfo ctor = t.GetConstructors(BindingFlags.Instance | BindingFlags.NonPublic)[0];
Object o = ctor.Invoke(new Object[] { });
return (PropertyItem) o;
}
private int DateTimeToInt(DateTime theDate)
{
return (int)(theDate.Date - new DateTime(1900, 1, 1)).TotalDays + 2;
}
// taken from https://codethis.wordpress.com/2008/11/ and modified for this example
static void DownloadAllPhotos(string DirectoryName, AtomEntryCollection photoList)
{
DirectoryInfo dirInfo = Directory.CreateDirectory(DirectoryName);
int photoNum = 1;
foreach (AtomEntry photo in photoList)
{
HttpWebRequest photoRequest = WebRequest.Create(photo.Content.AbsoluteUri) as HttpWebRequest;
HttpWebResponse photoResponse = photoRequest.GetResponse() as
HttpWebResponse;
BufferedStream bufferedStream = new BufferedStream(
photoResponse.GetResponseStream(), 1024);
BinaryReader reader = new BinaryReader(bufferedStream);
FileStream imgOut = File.Create(dirInfo.FullName + "\\image" +
photoNum++ + ".jpg");
BinaryWriter writer = new BinaryWriter(imgOut);
int bytesRead = 1;
byte[] buffer = new byte[1024];
while (bytesRead > 0)
{
bytesRead = reader.Read(buffer, 0, buffer.Length);
writer.Write(buffer, 0, bytesRead);
}
reader.Close();
reader.Dispose();
writer.Flush();
writer.Close();
writer.Dispose();
}
}
Пожалуйста, несите меня для публикации грязного кода, но я быстро взбивал это вместе.
Вы найдете две прокомментированные строки в коде выше, которые используют некоторые классы Exif, которые я нашел где-то в сети некоторое время назад. Поскольку они здесь, где слишком много кода раскрывают здесь, я загрузил их в Pastebin:
Хотя они только позволяют читать Exif, они, тем не менее, могут быть вам полезны, когда вы пытаетесь найти подходящие контенты PropertyItem для других тегов Exif.
Поскольку я не знаю, откуда этот код пришел, пожалуйста, напишите комментарий, если он/она сделает, поэтому я также могу добавить эту информацию здесь.