C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[8]: ファイルの生成時刻を撮影時刻にしたい


(過去ログ 41 を表示中)

[トピック内 13 記事 (1 - 13 表示)]  << 0 >>

■21513 / inTopicNo.1)  ファイルの生成時刻を撮影時刻にしたい
  
□投稿者/ kaoru (9回)-(2008/07/03(Thu) 16:52:43)

分類:[C#] 

いつもお世話になります。撮影時刻を首尾よくゲットしたものの、jpegファイルによっては当然撮影時刻が入っていないことがあります。そこで、Exifに撮影時刻が入っていなかったら、ファイルの生成時刻を撮影時刻にしたいと思います。現状では、撮影時刻が入っていない場合、ファイルパスもファイル名も取得できなくなってます。

先の
writer.WriteLine(Path.GetDirectoryName(nFileName) + "\t" + Path.GetFileName(nFileName) + "\t" + val.Trim());
の直前に撮影時刻が空だったら、生成時刻をゲットして、撮影時刻に書き込む、と書いたつもりの下記の5行を追加してみました。


if (val.Trim() = null) {
DateTime dtCreate = System.IO.File.GetCreationTime(nFileName);
System.IO.File.SetCreationTime(nFileName, DateTime.dtCreate.ToString());
return;
}

エラーメッセージは下記の通り。
エラー 1 代入式の左辺には変数、プロパティ、またはインデクサを指定してください。
エラー 2 型 'string' を型 'bool' に暗黙的に変換できません。
エラー 3 'System.DateTime' に 'dtCreate' の定義がありません。

定義は、
DateTime dtCreate = System.IO.File.GetCreationTime(nFileName);
でしたつもりなのですが、これも違っているんでしょうか?
ご教示いただければと思います。よろしくお願いします。

引用返信 編集キー/
■21514 / inTopicNo.2)  Re[1]: ファイルの生成時刻を撮影時刻にしたい
□投稿者/ いしだ (143回)-(2008/07/03(Thu) 17:02:28)
2008/07/03(Thu) 17:14:14 編集(投稿者)

ぱっとみ気づいたのは、

> if (val.Trim() = null) {
==

> System.IO.File.SetCreationTime(nFileName, DateTime.dtCreate.ToString());
System.IO.File.SetCreationTime(nFileName, dtCreate.ToString());

ですね。
valってstringですか?
nullで比較はいけないんじゃないでしょうか?

[編集]
stringをnullで初期化すれば、比較できましたね。
失礼しました。
引用返信 編集キー/
■21515 / inTopicNo.3)  Re[2]: ファイルの生成時刻を撮影時刻にしたい
□投稿者/ 山猫 (1回)-(2008/07/03(Thu) 17:06:48)
No21514 (いしだ さん) に返信
> 2008/07/03(Thu) 17:04:09 編集(投稿者)
>
> ぱっとみ気づいたのは、
>
>>if (val.Trim() = null) {
> ==
>
>>System.IO.File.SetCreationTime(nFileName, DateTime.dtCreate.ToString());
> System.IO.File.SetCreationTime(nFileName, dtCreate.ToString());
>
> ですね。
> valってstringですか?
> nullで比較はいけるのでしょうか?

そもそも、比較してないですね。
引用返信 編集キー/
■21516 / inTopicNo.4)  Re[2]: ファイルの生成時刻を撮影時刻にしたい
□投稿者/ kaoru (11回)-(2008/07/03(Thu) 17:14:18)
早速コメントありがとうございます。
すこしまえで

//文字列に変換する
string val = System.Text.Encoding.ASCII.GetString(item.Value);
val = val.Trim(new char[] { '\0' });

としているのですが、これはstringなのでしょうか?
ともあれ、次のように修正しました。

if (val.Trim() == null) {
DateTime dtCreate = System.IO.File.GetCreationTime(nFileName);
System.IO.File.SetCreationTime(nFileName, dtCreate.ToString());
return;
}

エラー 1 'System.IO.File.SetCreationTime(string, System.DateTime)' に最も適しているオーバーロード メソッドには無効な引数がいくつか含まれています。
エラー 2 引数 '2': 'string' から 'System.DateTime' に変換できません。
引き続きよろしくお願いします。


引用返信 編集キー/
■21517 / inTopicNo.5)  Re[3]: ファイルの生成時刻を撮影時刻にしたい
□投稿者/ いしだ (144回)-(2008/07/03(Thu) 17:17:13)
2008/07/03(Thu) 17:27:45 編集(投稿者)
2008/07/03(Thu) 17:21:07 編集(投稿者)

第2引数にはDateTime型を指定しろ、というエラーが出てますので、
> System.IO.File.SetCreationTime(nFileName, dtCreate.ToString());
のToString()がいりませんね。

[編集]
> //文字列に変換する
> string val = System.Text.Encoding.ASCII.GetString(item.Value);
> val = val.Trim(new char[] { '\0' });
このやり方だと、比較は出来ていないと思います。

[さらに編集]
> DateTime dtCreate = System.IO.File.GetCreationTime(nFileName);
> System.IO.File.SetCreationTime(nFileName, dtCreate.ToString());
GetCreationTimeで取得したDateTimeをSetCreationTimeしているようですが、
何も変わらないような気がするのですが。。。
(画像ファイルの撮影日時等の事は良くわかってなくて発言しています。)
引用返信 編集キー/
■21519 / inTopicNo.6)  Re[3]: ファイルの生成時刻を撮影時刻にしたい
□投稿者/ 山猫 (2回)-(2008/07/03(Thu) 17:35:16)
2008/07/03(Thu) 17:36:21 編集(投稿者)

No21516 (kaoru さん) に返信
> 早速コメントありがとうございます。
> すこしまえで
>
> //文字列に変換する
> string val = System.Text.Encoding.ASCII.GetString(item.Value);
> val = val.Trim(new char[] { '\0' });
>
> としているのですが、これはstringなのでしょうか?
> ともあれ、次のように修正しました。
>
> if (val.Trim() == null) {
> DateTime dtCreate = System.IO.File.GetCreationTime(nFileName);
> System.IO.File.SetCreationTime(nFileName, dtCreate.ToString());
> return;
> }
>
> エラー 1 'System.IO.File.SetCreationTime(string, System.DateTime)' に最も適しているオーバーロード メソッドには無効な引数がいくつか含まれています。
> エラー 2 引数 '2': 'string' から 'System.DateTime' に変換できません。
> 引き続きよろしくお願いします。

エラーはともかく、

> DateTime dtCreate = System.IO.File.GetCreationTime(nFileName);
> System.IO.File.SetCreationTime(nFileName, dtCreate.ToString());

これは、処理自体に意味がないと思います。

ファイルの作成日時を取って、ファイルの作成日時に設定って、もともと同じ項目ですよね。

っと、かぶっちゃいましたね。
引用返信 編集キー/
■21523 / inTopicNo.7)  Re[3]: ファイルの生成時刻を撮影時刻にしたい
□投稿者/ いしだ (145回)-(2008/07/03(Thu) 17:42:45)
DOBON.NET(画像のExif情報を取得する、設定する)
http://dobon.net/vb/dotnet/graphics/getexifinfo.html
ここが参考になると思いますよ。

http://cachu.xrea.jp/perl/ExifTAG.html
によると、
ID=36867(0x9003)
が撮影日時のようですね。
引用返信 編集キー/
■21524 / inTopicNo.8)  Re[3]: ファイルの生成時刻を撮影時刻にしたい
□投稿者/ kaoru (12回)-(2008/07/03(Thu) 17:47:06)
比較の書式を参考に、次のようにしてみました。

string stTarget2 = "NULL";
// stTarget1 の文字列と stTarget2 の文字列を比較する
int iCompare = string.CompareOrdinal(val, stTarget2);
// 比較した結果を表示する
if (iCompare != 0) {
DateTime dtCreate = System.IO.File.GetCreationTime(nFileName);
System.IO.File.SetCreationTime(nFileName, dtCreate.ToString());
return;
}

エラーメッセージはおなじでした。ということは、ひょっとして比較はうまくいっているけど、文字から時刻への変換がだめってことかな。
オーバーロードメソッドはいま勉強中…。

あ、エラーはともかく、Exifへの設定が違ってましたか…。
次はそちらを修正します。

引用返信 編集キー/
■21525 / inTopicNo.9)  Re[4]: ファイルの生成時刻を撮影時刻にしたい
□投稿者/ いしだ (146回)-(2008/07/03(Thu) 18:09:20)
これだと必ずif文の中が実行されてしまいますね。
BitmapクラスのPropertyIdListプロパティにIDが含まれているかで判断した方が
良いんじゃないでしょうか。
IDについては#21523をみてください。

エラーについては、#21517をみて下さい。

引用返信 編集キー/
■21526 / inTopicNo.10)  Re[5]: ファイルの生成時刻を撮影時刻にしたい
□投稿者/ kaoru (13回)-(2008/07/03(Thu) 18:11:00)
string saveFile = "nFineName_add";
//撮影時刻
string time = dt;
//画像を読み込む
System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(nFileName);

if (bmp.PropertyItems == null || bmp.PropertyItems.Length == 0)
return;
//とにかくPropertyItemオブジェクトを取得する
System.Drawing.Imaging.PropertyItem pi = bmp.PropertyItems[0];
pi.Id = 0x9003;//Id 0x9003は撮影時刻
pi.Type = 7; //Typeは1はByte、2はASCII 形式でエンコードされたByteオブジェクトの配列、3は16ビット整数、4は32ビット整数、5は有理数を表すふたつのByteオブジェクトの配列、6は未使用、7は未定義、8は未使用、9はSLong、10はSRationalである。
//コメントの前に'\0'を8バイト入れる
val = new string('\0', 8) + dtCreate;
pi.Value = System.Text.Encoding.GetEncoding("shift_jis").GetBytes(val);
pi.Len = pi.Value.Length;
//格納する
bmp.SetPropertyItem(pi);
//保存する
bmp.Save(saveFile, System.Drawing.Imaging.ImageFormat.Jpeg);
bmp.Dispose();
return;
}

なんか、たくさん書くことがあって、頭のなかはかなり混乱…。う〜む。
エラー 1 ローカルの変数 'bmp' をこのスコープで宣言することはできません。これは、'親またはカレント' スコープで別の意味を持つ 'bmp' の意味が変更されるのを避けるためです。

え〜と、もとのファイルを.original、新しい撮影時刻にファイルの生成時刻を設定したファイルをもとのファイル名にしたいのですが、それはもうちょっとしてからですかね。
いろいろ手を出して頭がついていってない…。

引用返信 編集キー/
■21527 / inTopicNo.11)  Re[6]: ファイルの生成時刻を撮影時刻にしたい
□投稿者/ kaoru (15回)-(2008/07/03(Thu) 18:25:17)
すみません。自分でなにを書いているのかわからなくなってしまいました。
もういちど原点に戻ります。

撮影時刻が入っていないJPEGファイルは、ファイルの生成時刻を撮影時刻に追記したい。

出力する直前に、その処理を入れるのがよいと思われる。直前とは、
writer.WriteLine(Path.GetDirectoryName(nFileName) + "\t" + Path.GetFileName(nFileName) + "\t" + val.Trim());
の行の前。

することは、
・撮影時刻を得る。val.Trim
・撮影時刻が空かどうかを比較する。いまの書き方だとここでif文のなかがつねに実行されるので、#21523を参照すること。比較は、http://jeanne.wankuma.com/tips/csharp/string/compare.htmlを参照すること。
・空だったら、生成時刻を得る。
DateTime dtCreate = System.IO.File.GetCreationTime(nFileName);
・生成時刻を撮影時刻のタグに書き込む。
http://dobon.net/vb/dotnet/graphics/getexifinfo.html
DOBON.NET(画像のExif情報を取得する、設定する)を参照する。
撮影時刻のタグは、
http://cachu.xrea.jp/perl/ExifTAG.html
によると、
ID=36867(0x9003)

引用返信 編集キー/
■21531 / inTopicNo.12)  Re[7]: ファイルの生成時刻を撮影時刻にしたい
□投稿者/ いしだ (147回)-(2008/07/03(Thu) 19:27:48)
2008/07/03(Thu) 19:50:20 編集(投稿者)
撮影日時を設定する方法は、例えば以下のような感じです。
上書き保存はどうするか等、まだ問題はありますが。

Bitmap bitmap = new Bitmap(@"C:\test.jpg");
if (Array.IndexOf(bitmap.PropertyIdList, 0x9003) < 0) // 撮影日時が設定されていない
{
    PropertyItem propItem = bitmap.PropertyItems[0];
    propItem.Type = 2;
    propItem.Id = 0x9003;
    propItem.Value = Encoding.GetEncoding("shift_jis")
            .GetBytes(File.GetCreationTime(@"C:\test.jpg")
            .ToString("yyyy:MM:dd HH:mm:ss") + '\0');
    propItem.Len = propItem.Value.Length;
    bitmap.SetPropertyItem(propItem);
    bitmap.Save(@"C:\test2.jpg", ImageFormat.Jpeg);
}
bitmap.Dispose();

引用返信 編集キー/
■21533 / inTopicNo.13)  Re[8]: ファイルの生成時刻を撮影時刻にしたい
□投稿者/ kaoru (16回)-(2008/07/03(Thu) 19:54:46)
No21531 (いしだ さん) に返信

いしださん。ありがとうございました。
せっかく書いていただいたのですが、ちょっとわたしの頭がついていってなくて、これはこれとしてしばらく寝かせてから考えたいと思います。すみません。
習うより慣れろといいつつほとんど教わってばかりですが、やりたいことが多く、できるところからという感じです。
で、メインの処理のほうでエラーが出ているので、そちらの質問を優先させていただけないでしょうか。そういう場合、新規の質問とした方がよいのかな。とりあえず新規の質問にしてみます。

引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -