- 題名: 写真の取得日付変更の件
- 日時: 2015/01/23 14:42:04
- ID: 32799
- この記事の返信元:
- (なし)
- この記事への返信:
- [32803] Re[1]: 写真の取得日付変更の件2015/01/23 17:30:12
- ツリーを表示
とりあえず、jpeg/tiff/pngについては、System.Windows.Media.Imagingを使うことでどうにかできるようです。
使用するにはPresentationCore.dllを参照に追加する必要があります(それ以外にも必要かもしれませんが)。
手順としては、
1. BitmapDecoder.Createでファイルをロードする。
https://msdn.microsoft.com/ja-jp/library/system.windows.media.imaging.bitmapdecoder.aspx
このとき、Uriだと書き込めないっぽいのでFileStreamを使います。
2. BitmapDecoder.Frames(0).CreateInPlaceBitmapMetadataWriterでInPlaceBitmapMetadataWriterを作成する。
設定先はファイル形式毎に手順が異なっていて、
a. jpegの場合: writer.SetQuery("/xmp/MicrosoftPhoto:DateAcquired", datetime.ToString("o"))
b. tiffの場合: writer.SetQuery("/ifd/{ushort=700}/MicrosoftPhoto:DateAcquired", datetime.ToString("o"))
c. png の場合: writer.DateTaken = datetime
で、最後に
writer.TrySave()
で保存します。
■No32807に返信(Hongliangさんの記事)
早速のご回答有難うございます。
昨日の時点で、回答されていたのはわかっていたのですが、用語がわからずに1文字1文字ネットで調べておりました。
結果、コードらしきものはできたのですが、写真のプロパティの詳細タブの「取得日時」に反映されず、困っています。
コードを提示しますので、どこが悪いかご指摘いただけるとありがたいのですが。
○参照設定
・PresentationCore
・WindowsBase
・System.Xml(Xamlが見つからないため)
○コード
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
'画像ファイルデータをStreamで開く
Dim imageFileStrm As New FileStream(TextBox1.Text, _
FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite)
'BitmapDecoderを作成する
Dim decoder As BitmapDecoder = BitmapDecoder.Create(imageFileStrm, _
BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default)
Dim writer As InPlaceBitmapMetadataWriter = decoder.Frames(0).CreateInPlaceBitmapMetadataWriter()
Dim d, f As String
Dim dt As DateTime
d = "2004/08/24 20:23:06"
f = "yyyy/MM/dd HH:mm:ss"
dt = DateTime.ParseExact(d, f, Nothing)
If writer.TrySave() = True Then
writer.SetQuery("/xmp/MicrosoftPhoto:DateAcquired", dt.ToString("o"))
End If
imageFileStrm.Close()
End Sub
Private Sub TextBox1_DragDrop(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles TextBox1.DragDrop
'コントロール内にドロップされたとき実行される
'ドロップされたすべてのファイル名を取得する
Dim fileName As String() = CType( _
e.Data.GetData(DataFormats.FileDrop, False), _
String())
TextBox1.Text = fileName(0)
End Sub
Private Sub TextBox1_DragEnter(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles TextBox1.DragEnter
'コントロール内にドラッグされたとき実行される
If e.Data.GetDataPresent(DataFormats.FileDrop) Then
'ドラッグされたデータ形式を調べ、ファイルのときはコピーとする
e.Effect = DragDropEffects.Copy
Else
'ファイル以外は受け付けない
e.Effect = DragDropEffects.None
End If
End Sub
○参照URL
・http://www.atmarkit.co.jp/fdotnet/dotnettips/203dateparse/dateparse.html
・https://msdn.microsoft.com/ja-jp/library/system.windows.media.imaging.bitmapframe.createinplacebitmapmetadatawriter(v=vs.110).aspx?cs-save-lang=1&cs-lang=vb
・http://dobon.net/vb/dotnet/control/droppedfile.html
・http://dobon.net/vb/dotnet/graphics/selectactiveframe.html
・http://dobon.net/vb/dotnet/string/datetimeformat.html
以上です。
なにとぞ、ご指南ください。
InPlaceBitmapMetadataWriterのMSDNサンプルを元にお書きになったと思うのですが、
> If writer.TrySave() = True Then
> writer.SetQuery("/xmp/MicrosoftPhoto:DateAcquired", dt.ToString("o"))
> End If
この部分、TrySaveはSetQueryの後です(一応私も先の投稿で明示したんですが)。
普通に考えて、Saveしてから値を設定しても意味ないですよね。
■No32810に返信(Hongliangさんの記事)
> InPlaceBitmapMetadataWriterのMSDNサンプルを元にお書きになったと思うのですが、
> この部分、TrySaveはSetQueryの後です(一応私も先の投稿で明示したんですが)。
> 普通に考えて、Saveしてから値を設定しても意味ないですよね。
全く仰るとおりです。
If writer.TrySave() = True Then
writer.SetQuery("/xmp/MicrosoftPhoto:DateAcquired", dt.ToString("o"))
End If
と
writer.SetQuery("/xmp/MicrosoftPhoto:DateAcquired", dt.ToString("o"))
writer.TrySave()
の両方を試してみましたが、どちらも反映されなかったので、MSDNサンプルが正しいのかなと思って、そのままにしてしまいました。
お叱りを頂いて、おそらくdt.ToString("o")の部分が機能していないのかなと思って、空文字列""にしてみたところ、
「取得日時」設定済みのファイルでは「取得日時」が消えたので、dt.ToString("o")の部分に問題があることに確信が持てました。
手元に「取得日付」が設定されたものがなかったために、確認が遅れました。
ToString()の書式もよくわかなかったために、かたっぱしから下記参照URLの書式を入れていったところ、
小文字のs("s")で設定日付が反映されたため、この部分を書き換える必要があったことがわかりました。
Windows7の32bitと64bitの両方で試してみましたが、どちらも"s"で設定でき"o"では設定できませんでした。なぜかは不明です。
とにかく、いろいろをご迷惑をお掛けしつつ、設定できるコードが完成しました。
親切なご指南ありがとうございました。
最後になりましたが、完成したコードと参照URLを上げておきます。
ありがとうございました。
○写真の取得日付を設定するコード(jpg対象)
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
'画像ファイルデータをStreamで開く
Dim imageFileStrm As New FileStream(TextBox1.Text, _
FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite)
'BitmapDecoderを作成する
Dim decoder As BitmapDecoder = BitmapDecoder.Create(imageFileStrm, _
BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default)
Dim writer As InPlaceBitmapMetadataWriter = decoder.Frames(0).CreateInPlaceBitmapMetadataWriter()
Dim d, f As String
Dim dt As DateTime
d = "2004/08/24 20:23:06"
f = "yyyy/MM/dd HH:mm:ss"
dt = DateTime.ParseExact(d, f, Nothing)
writer.SetQuery("/xmp/MicrosoftPhoto:DateAcquired", dt.ToString("s"))
Dim Ret as Boolean = writer.TrySave()
imageFileStrm.Close()
End Sub
Private Sub TextBox1_DragDrop(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles TextBox1.DragDrop
'コントロール内にドロップされたとき実行される
'ドロップされたすべてのファイル名を取得する
Dim fileName As String() = CType( _
e.Data.GetData(DataFormats.FileDrop, False), _
String())
TextBox1.Text = fileName(0)
End Sub
Private Sub TextBox1_DragEnter(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles TextBox1.DragEnter
'コントロール内にドラッグされたとき実行される
If e.Data.GetDataPresent(DataFormats.FileDrop) Then
'ドラッグされたデータ形式を調べ、ファイルのときはコピーとする
e.Effect = DragDropEffects.Copy
Else
'ファイル以外は受け付けない
e.Effect = DragDropEffects.None
End If
End Sub
○参照URL
・ToString 標準の日時書式指定文字列
http://dobon.net/vb/dotnet/string/datetimeformat.html
・その他
・http://www.atmarkit.co.jp/fdotnet/dotnettips/203dateparse/dateparse.html
・https://msdn.microsoft.com/ja-jp/library/system.windows.media.imaging.bitmapframe.createinplacebitmapmetadatawriter(v=vs.110).aspx?cs-save-lang=1&cs-lang=vb
・http://dobon.net/vb/dotnet/control/droppedfile.html
・http://dobon.net/vb/dotnet/graphics/selectactiveframe.html
・http://dobon.net/vb/dotnet/string/datetimeformat.html
分類:[.NET]
お世話になります。
写真をとってPCに移動すると、その写真のプロパティの詳細タブの中に、元の場所という項目があって、その中に取得日付という項目があります。
この「取得日付」がプログラムで変更できません。
撮影日付とか、作成日付、更新日付、アクセス日付等は変更できたのですが、この「取得日付」だけはID等を見つけることができませんでした。
削除する方法だけは探しだしたのですが、できればプログラムで変更したいです。
ご存知のかた、情報の載っているサイト情報でも結構ですので、お教え下さい。