.NETプログラミング研究 第2号 †
ご挨拶 †
前回の「.NETプログラミング研究 創刊号」は私が生まれて始めて作成したメールマガジンでした。失敗しなかったかと不安でいっぱいでしたが、幸い苦情はなく、大成功とは行かないまでも、無難にはできたかなと胸をなでおろしています。
さて今回から試しにVB.NETだけでなくC#でのサンプルコードも載せることにしました。果たしてこの方がいいか、あるいはどちらかのコードだけで十分かご意見がありましたらお聞かせください。
.NET Tips †
画像を拡大、縮小して表示する †
画像を拡大、縮小して表示する方法(スケーリング)を紹介します。Graphicsクラス(System.Drawing名前空間)のDrawImageメソッドで表示するサイズを指定することにより、簡単にできます。次の例ではもとの画像("C:\サンプル.jpg")を1.5倍に拡大してPictureBox1に表示しています。ここではGraphics.DrawImage(Image, Single, Single, Single, Single)を使いましたが、他のDrawImageのオーバーロードを使用する方法も考えられます。
1
2
3
4
5
6
7
8
9
| | Dim image = New Bitmap("C:\サンプル.jpg")
Dim g As Graphics = PictureBox1.CreateGraphics()
Dim rect As New RectangleF(0, 0, 1.5F * image.Width, _
1.5F * image.Height)
g.DrawImage(image, rect)
|
1
2
3
4
5
6
7
8
9
| | Bitmap image = new Bitmap(@"C:\サンプル.jpg");
Graphics g = PictureBox1.CreateGraphics();
RectangleF rect = new RectangleF(0, 0, 1.5F * image.Width,
1.5F * image.Height);
g.DrawImage(image, rect);
|
さらにGraphics.InterpolationModeプロパティにより、画像を拡大、縮小表示する時の補間方法を変更することができます。このInterpolationMode列挙体のメンバにはBicubic(双三次補間)、Bilinear(双一次補間)、Default(既定のモード)、High(高品質補間)、HighQualityBicubic(高品質双三次補間)、HighQualityBilinear(高品質双一次補間)、Invalid(QualityMode列挙体の要素Invalidと等価)、Low(低品質補間)、NearestNeighbor(最近傍補間)があります。当たり前のことですが、一般的に高品質の補間方法を指定したときのほうが表示に時間がかかります。
「アスキーデジタル用語辞典」によると、「ニアレストネイバー法はその名の通り、単純に元の画像を水増し(拡大)、間引き(縮小)する方式。ジャギーが目立ちやすく階調のある画像のリサイズにはむいていない。バイリニア法、バイキュービック法は元の画像の周辺の複数の画像を数学的に算出して拡大、縮小する。バイキュービック法のほうが計算が複雑で精度が高く階調のある画像のリサイズにむいている。」とのことです。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| | Dim image = New Bitmap("C:\サンプル.jpg")
Dim g As Graphics = PictureBox1.CreateGraphics()
g.InterpolationMode = _
System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor
g.DrawImage(image, 0, 0, 150, 120)
g.InterpolationMode = _
System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic
g.DrawImage(image, 160, 0, 150, 120)
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| | Bitmap image = new Bitmap(@"C:\サンプル.jpg");
Graphics g = PictureBox1.CreateGraphics();
g.InterpolationMode =
System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor;
g.DrawImage(image, 0, 0, 150, 120);
g.InterpolationMode =
System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
g.DrawImage(image, 160, 0, 150, 120);
|
最後にサムネールイメージ(縮小イメージ)の作成方法を紹介します。サムネールイメージを作成するにはImage.GetThumbnailImageメソッド使用します。
1
2
3
4
5
6
7
8
9
| | Dim myBitmap = New Bitmap("C:\納屋.jpg")
Dim g As Graphics = PictureBox1.CreateGraphics()
Dim myThumbnail As Image = myBitmap.GetThumbnailImage(100, 100, Nothing, IntPtr.Zero)
g.DrawImage(myThumbnail, 0, 0)
|
1
2
3
4
5
6
7
8
9
10
| | Bitmap myBitmap = new Bitmap(@"C:\納屋.jpg");
Graphics g = PictureBox1.CreateGraphics();
Image myThumbnail =
myBitmap.GetThumbnailImage(100, 100, null, IntPtr.Zero);
g.DrawImage(myThumbnail, 0, 0);
|
画像の拡大、縮小表示とはあまり関係のないことかもしれませんが、最後の最後に自動スケーリングについて触れておきます。
元の画像と同じ大きさで表示するには
g.DrawImage(image, 10, 20)
のように表示する左上の座標を指定するだけでDrawImageメソッドを使用できますが、この時「自動スケーリング」が行われる可能性があり、パフォーマンスは低下します。「自動スケーリング」を解除するためには
g.DrawImage(image, 10, 20, image.Width, image.Height)
のように幅と高さをちゃんと指定してあげます。詳しくはヘルプの「自動スケーリングの解除によるパフォーマンスの向上」をご覧ください。
VBユーザーのためのC# †
C#でLike演算子と同じことをするには? †
C#にVBのLike演算子はありません。これと同等の事を行うには、Regexクラス(System.Text.RegularExpression名前空間)のIsMatchメソッドを使う方法(つまり正規表現を使う方法)があります。Like演算子の"*"、"?"、"#"はそれぞれ正規表現では".*"、"."、"\d"に置き換えることが出来ます(ただし正規表現の".*"、"."は改行文字以外の文字となります)。Like演算子の"[]"は正規表現でも"[]"で、Like演算子の"[!]"は正規表現では"[^]"と表現できます。
正規表現の"."は改行文字以外の文字を表すため、改行文字を含む文字列の比較では同一の結果とならないかもしれません。このような時は一致オプションにRegexOptions.Singlelineを指定し、単一行モードとします。このことにより、"."はすべての文字と一致するようになります。
さらに、Like演算子は2つの文字列が完全に一致するかを調べるのに対して、IsMatchメソッドは一致する箇所があるが調べるものです。よって、IsMatchメソッドでは検索パターン文字列の前後に"^"と"$"を付ける必要がありそうです。
当然ですが、検索パターン文字列に正規表現で使われるメタ文字が含まれているときは、これをエスケープしておかなければいけません。(これはRegex.Escapeメソッドを使うことにより行えます。)
実際にこの変換を使用した例を下に示します。この例ではVBのLike演算子のヘルプでのサンプルをC#に変換してみました。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
| |
bool myCheck;
myCheck = Regex.IsMatch("F", "^F$", RegexOptions.Singleline);
myCheck = Regex.IsMatch("F", "^f$", RegexOptions.Singleline);
myCheck = Regex.IsMatch("F", "^FFF$", RegexOptions.Singleline);
myCheck =
Regex.IsMatch("aBBBa", "^a.*a$", RegexOptions.Singleline);
myCheck =
Regex.IsMatch("F", "^[A-Z]$", RegexOptions.Singleline);
myCheck =
Regex.IsMatch("F", "^[^A-Z]$", RegexOptions.Singleline);
myCheck =
Regex.IsMatch("a2a", "^a\\da$", RegexOptions.Singleline);
myCheck = Regex.IsMatch(
"aM5b", "^a[L-P]\\d[^c-e]$", RegexOptions.Singleline);
myCheck = Regex.IsMatch(
"BAT123khg", "^B.T.*$", RegexOptions.Singleline);
myCheck = Regex.IsMatch(
"CAT123khg", "^B.T.*$", RegexOptions.Singleline);
|
コメント †