[C#] 時間が掛かる処理で進行状況を表示する

時間が掛かる処理では進行況を表示して、かつ、処理を中断できるようにしたほうがいい。

以下、進行状況ダイアログを表示するサンプル。これをたたき台にして、ダイアログに進行状況を示すメッセージやプログレスバーなどを追加しよう。

progress_dialog

[C#] 連想配列を使う (Dictionaryクラス)

連想配列を使って英文中の単語の出現回数をカウントするサンプル。

参考サイト

Dictionary(TKey, TValue) クラス (System.Collections.Generic)
http://msdn.microsoft.com/ja-jp/library/xfhwa508(v=vs.110).aspx

[C#] 文字列を区切り文字で分割する

テキストファイルから英文を読み込んで単語に分割するサンプル。

参考サイト

方法 : 文字列を分割する (C# プログラミング ガイド)
http://msdn.microsoft.com/ja-jp/library/ms228388.aspx

[C#] 文字列を数値に変換する

フォームに配置したテキストボックスに入力された文字列を数値に変換するような場合を想定。

以下に2つの方法を示す。何れの場合も変換できなければ例外が投げられるので、例外をキャッチしたらメッセージを表示してユーザに再入力を促せば良い。

<型>.Parse()メソッドを使う

Int16.Parse メソッド (System)
http://msdn.microsoft.com/ja-jp/library/system.int16.parse(v=vs.110).aspx

Decimal.Parse メソッド (System)
http://msdn.microsoft.com/ja-jp/library/system.decimal.parse(v=vs.110).aspx

Single.Parse メソッド (System)
http://msdn.microsoft.com/ja-jp/library/system.single.parse(v=vs.110).aspx

System.Convertクラスを使う

Convert クラス (System)
http://msdn.microsoft.com/ja-jp/library/system.convert(v=vs.110).aspx

[C#] 画像を矩形で切り取る (Bitmap.Clone)

以前にも同じ処理について書いたけど、MSDNを眺めていたら別の方法を見つけたので試してみる。

Bitmap.Clone メソッド (Rectangle, PixelFormat) (System.Drawing)
http://msdn.microsoft.com/ja-jp/library/ms141944(v=vs.110).aspx

コードはたった2行。ちなみに以前に書いたGraphicsオブジェクトを使う処理だと

コードは6行になる。単純計算でコーディング量は3倍。まあ、2行でも6行でも大した量じゃないけど。

処理速度の比較 – Bitmap.Cloneメソッド vs Graphicsオブジェクト

パフォーマンスが同じならコーディング量は少ないほうがいい。処理速度を検証しよう。

特定ディレクトリ中の70個のJPEGファイルをスキャンして、1つずつ読み込んで固定サイズに切り取り、別フォルダに保存し直すだけのプログラムを書いた。それぞれの方法で10回ずつ処理して所要時間を計測してみる。

テスト結果 (処理時間)

結果はBitmap.Cloneを使った切り取り処理のほうが倍近く遅かった。

Bitmap.Cloneメソッドは簡単だけど処理は遅いという結論。

[C#] あちこちでいろんな使われ方をしているので、自分なりにJPEGやEXIFの用語定義を再確認してみた

C#のプログラミングとは直接関係無い話だけど、EXIFデータを使った画像処理の必要がありネットでいろいろ調べてみたところ、記事によってJPEGだのEXIFだの用語の使い方がいい加減なので、自分なりに整理してみた。

JPEGは圧縮方式、あるいはファイル形式のこと

もともとJPEGは「Joint Photographic Experts Group]という団体の略称。その団体が立案したデジタル画像の圧縮方式が、団体の略称をそのまま使ってJPEGと呼ばれている。JPEG方式で圧縮したデジタル画像を格納するファイル形式の規格は存在しなかったので、C-Cube Microsystems社が「JPEG File Interchange Format (JFIF)」というファイル形式を立案した。そのファイルが広く使われるようになってJPEGファイル形式と呼ばれるようになった。というわけで、一口にJPEGと言っても、デジタル画像の圧縮形式を指す場合と、デジタル画像のファイル形式を指す場合があるわけだ。JPEG圧縮されたデジタル画像は必ずJPEGファイル形式で保存されるとは限らない。TIFFファイル形式に保存されることだって普通にある。

JPEG – Wikipedia
http://ja.wikipedia.org/wiki/JPEG

JPEG homepage
http://www.jpeg.org/jpeg/

EXIFは画像ファイル形式の「規格」である

EXIFは「Exchangeable image file format」の略称。参考サイトの説明には、「デジタルカメラで撮影した画像データに、撮影条件に関する情報(メタデータ)を追加して保存できる、画像ファイル形式の規格のことである」とある。解りにくい表現だな。僕は「メタデータの仕様とそれを画像データにどのように付加して保存するかのルールを定めているのがEXIF」と認識している。ネットの記事などで「EXIFはファイル形式」という説明を良く見かけるけど、ファイルの物理構造を定義するものをファイル形式と呼ぶならば、それは正しいとは言いがたい。EXIFデータ付きの画像データは「JPEGファイル形式(圧縮の場合)」または「TIFFファイル形式(非圧縮の場合)」に保存されるから。

Exifとは (Exchangeable image file format) エグジフ: – IT用語辞典バイナリ
http://www.sophia-it.com/content/Exif

Exchangeable image file format – Wikipedia
http://ja.wikipedia.org/wiki/Exchangeable_image_file_format

JPEGファイル構造の基礎知識

以下のサイトの説明がわかりやすい。

JpegAnalyzer Plusオンラインヘルプ
http://hp.vector.co.jp/authors/VA032610/

JPEGファイルの構造
http://hp.vector.co.jp/authors/VA032610/JPEGFormat/StructureOfJPEG.htm

Exifについて
http://hp.vector.co.jp/authors/VA032610/JPEGFormat/AboutExif.htm

JPEGファイルには、セグメントと呼ばれるブロック分けされたデータ群とJPEG方式で圧縮された画像データが格納されている。セグメント先頭に「マーカー」と呼ばれる識別子があって、マーカー「APP1」がEXIFデータのセグメントを指す。アプリは自分が理解できないセグメントを読み飛ばすことにより、カメラやソフトのメーカーが独自定義した未知のセグメントが含まれていようと、アプリ間での画像データの受け渡しが可能となる。

[C#] MSDN/.NETのFileStreamコンストラクタの説明の和訳に誤り

MSDNには.NETのクラスの日本語マニュアルがあるけど、それぞれのページの冒頭に「この記事は機械翻訳されたものです。 記事の文章にポインターを重ねると、原文のテキストが表示されます。」という記述がある。これから推察するに、訳文の正当性チェックはさほど細かく行われていないのかもしれない。

先日関数の引数を調べていて、和訳された記述が原文とは違った意味になっている箇所があった。最初日本語の説明を読んでいたのだけど、おかしいなと思って原文を見直したところ気付いたのだけど、こうしてブログに書いておくと誰かの役に立つかもしれないので覚え書き。

FileStream コンストラクター (IntPtr, FileAccess, Boolean, Int32) (System.IO)
http://msdn.microsoft.com/ja-jp/library/w4z40ebc(v=vs.110).aspx

bufferSize
Type: System.Int32
A positive Int32 value greater than 0 indicating the buffer size. For bufferSize values between one and eight, the actual buffer size is set to eight bytes.

bufferSize
型 : System.Int32
バッファー サイズを示す 0 より大きな正の Int32 値。 bufferSize 値には 1 から 8 を設定します。実際のバッファー サイズは 8 バイトに設定されます。 1から8の間の値をbufferSizeに指定すると、実際のバッファサイズは8バイトに設定されます。(つまり、適用されるbufferSizeの最小値は8となる)

[C#] 画像を矩形で切り取る

Graphicsオブジェクトを使うと、画像の切り取りも比較的簡単に行うことができる。

切り取り後の画像サイズのビットマップを作成し、矩形領域を指定して元画像をDrawImageするだけ。

[C#] INIファイルを読み書きする

Windowsにはアプリの設定を保存する方法がいくつかある。古い順に挙げるとINIファイル、レジストリ、XMLファイルなど。中でもINIファイルは、取り扱いが楽なのでいまだに使われている現場もある。エディタで開いて自由に設定を変更できるし、アンインストール時にレジストリにゴミを残す心配も無い。

C#でINIファイルを読み書きするには、WindowsのDLLをインポートすることで、Windows APIとして提供されているINIファイルのアクセス関数を使うのが手っ取り早い。

参考までに自作クラスを紹介しておく。

[C#] 画像ファイルからExif情報を削除するには

前回のエントリの内容を試行錯誤している間に見つけた方法。ちょっと裏技っぽいけど。

「Exif情報付き画像ファイルから作成したBitmapオブジェクトを複製したものを画像ファイルに保存すると、保存された画像ファイルにはExif情報が付加されない」。

保存した画像ファイルにはExif情報は付加されていなかった。想像だけど、元画像ファイルの情報は複製したBitmapオブジェクトに引き継がれないので、元画像ファイルから保存先ファイルにExif情報が転記されないのだと思う。だけど、こういったBitmapクラスの挙動はMSDNなどドキュメントに記載されていないので、将来.NETがバージョンアップしたときには振る舞いが変わっている可能性があるかもしれない。このテクニックの活用には注意が必要だ。