DOBON.NET DOBON.NETプログラミング掲示板過去ログ

C# pictureBoxへのbmp画像回転貼付時の外周欠け

環境/言語:[WindowsXP C# VS2005]
分類:[.NET]

判りやすいように外周を左辺:赤・下辺:緑・右辺:紫・上辺:青で
塗った32*32の24bitビットマップを
回転させてピクチャボックスに貼付けてます。

回転無しの場合はいいのですが、180°で回転させると
二辺の外周が欠けてしまいます。
90°、270°では1辺が欠けました。
このようになる原因がわかる方、いらっしゃいますでしょうか?

因みに使用したサンプルコードは下記の通りです。
フォームにピクチャボックスとボタンを設けてクリックするだけのコードです。
−−−−−−サンプルコード
  private void button1_Click(object sender, EventArgs e)
  {
    Image Img;
    string path=GetExeAppPath();
    path+="\\Rect.bmp";
    Img = Image.FromFile(path);

    Graphics g = pictureBox1.CreateGraphics();
  
    //右側に回転無しで描画
    g.DrawImage(Img, new Point(100, 0));

    //左側に画像の中央で180度回転させて描画
    Matrix mx = new Matrix();
    mx.RotateAt(180, new Point(Img.Width / 2, Img.Height / 2));
    g.Transform = mx;
    g.DrawImage(Img, new Point(0, 0));
  }
−−−−−−サンプルコード

環境は、
WindowsXP 32bit版 VS2005 と
Windows7 64bit版 VS2010 でも
両方で出ました。
よろしくお願いします。
添付ファイル: 1365486490.png (6 KB)
90, 180, 270度でいいのなら、ImageクラスのRotateFlipメソッドではどうですか?

http://dobon.net/vb/dotnet/graphics/rotateflip.html
■No31465に返信(alさんの記事)
> 90°、270°では1辺が欠けました。
g.PixelOffsetMode を Half や HighQuality などに変更してみてください。

> 因みに使用したサンプルコードは下記の通りです。
変数 Img や g を .Dispose() し忘れていますよ。


> フォームにピクチャボックスとボタンを設けてクリックするだけのコードです。
本題とは関係ありませんが、CreateGraphics の利用はできれば避けましょう。

一般的なアプリでは、Paint イベントの e.Graphics に描画するか、
または new Bitmap(x,y); 等で生成した Bitmap に対して、
Graphics.FromImage して描画した後、その Bitmap を
PictureBox のImage/BackgroundImage に割り当てた方が好ましいです。
■No31466に返信(すみださんの記事)
> 90, 180, 270度でいいのなら、ImageクラスのRotateFlipメソッドではどうですか?
>
> http://dobon.net/vb/dotnet/graphics/rotateflip.html

回答ありがとうございます。
実際は30°単位で回転させてみて、90, 180, 270が
欠けるという内容でした。
長くなるといけないと思って、欠ける部分のみ質問して
しまいました。説明不足で本当にすみません。

でもこれだと特にオフセット等意識しないで出来そうなので、
わかりやすいですね。
勉強になります。ありがとうございました。
■No31467に返信(魔界の仮面弁士さんの記事)
> ■No31465に返信(alさんの記事)
>>90°、270°では1辺が欠けました。
> g.PixelOffsetMode を Half や HighQuality などに変更してみてください。

g.PixelOffsetMode = PixelOffsetMode.Half;で欠けないようになりました。
ありがとうございました。
ただ、画像の辺が奇数値か偶数値かでまだ、欠けたりしますが、
RotateAt や、 DrawImageの座標を調整して対応できるのではと思います。

> 変数 Img や g を .Dispose() し忘れていますよ。
> 本題とは関係ありませんが、CreateGraphics の利用はできれば避けましょう。
> 一般的なアプリでは、Paint イベントの e.Graphics に描画するか、

今のコードでは、他の画面が上に来ると消えてしまうので、
Paint イベントを使ってみようと思います。
適切なアドバイスも頂き本当に、ありがとうございました。
C#は始めたばかりですので、これから頑張ります。

DOBON.NET | プログラミング道 | プログラミング掲示板