tagCANDY CGI VBレスキュー(花ちゃん) の Visual Basic 2010 用 掲示板(VB.NET 掲示板) [ツリー表示へ]   [Home]
一括表示(VB.NET VB2005)
タイトル画像の回転について
記事No6822
投稿日: 2008/01/13(Sun) 13:34
投稿者もりまさ
はじめまして。
表題の件について教えてください。(VB2005で作成)

GIFアニメの画像を180度回転させようと調べたのですが

Picture.Image = Image.FromFile("C:\anime.GIF")
Picture.Image.RotateFlip(RotateFlipType.Rotate180FlipNone)

で、回転させる事はできましたが、
GIFアニメが1コマ目しか表示されません。(回転させなければアニメは動作する)

何か解決策ありませんでしょうか。

[ツリー表示へ]
タイトルRe: 画像の回転について
記事No6824
投稿日: 2008/01/13(Sun) 17:52
投稿者Hongliang
RotateNoneFlipNone 以外の RotateFlipType を適用した時点で Image は Gif から MemoryBmp に差し替わりますので(RawFormat プロパティで確認できます)、フレーム情報等も破棄されてしまいます。これは使用できません。
ImageAnimator を使うなりして変更タイミングを取得&フレームの切り替えを行い(ImageAnimator はこの両方の処理を受け持ってくれるヘルパクラスです)、自分で描画することでアニメーションさせることが可能です。
回転については、実際に描画するときに Graphics の RotateTransform や TranslateTransform で回転させましょう。

[ツリー表示へ]
タイトルRe^2: 画像の回転について
記事No6827
投稿日: 2008/01/13(Sun) 22:18
投稿者もりまさ
Hongliangさん、返答ありがとうございます。
いろいろ検索してみて処理を編集してみました
しかし、RotateTransformを180度にしてみるとGIFアニメが1コマ目しか表示されません。
(90、270などはアニメーションされます)
私のソースに問題があるのでしょうか。

    Private P_image As System.Drawing.Bitmap

    Private Sub Form_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        P_image = New Bitmap("C:\anim.gif")
        AddHandler Me.Paint,New PaintEventHandler(AddressOf Me.Form_Paint)
        System.Drawing.ImageAnimator.Animate(P_image, _
            New EventHandler(AddressOf Me.Image_FrameChanged))
    End Sub

    Private Sub Image_FrameChanged(ByVal o As Object, ByVal e As EventArgs)
        Me.Invalidate()
    End Sub

    Private Sub Form_Paint(ByVal sender As Object, _
            ByVal e As PaintEventArgs)
        System.Drawing.ImageAnimator.UpdateFrames(P_image)
        e.Graphics.TranslateTransform(70, 70)
        e.Graphics.RotateTransform(180)
        e.Graphics.DrawImage(P_image, 0, 0)
    End Sub

[ツリー表示へ]
タイトルRe^3: 画像の回転について
記事No6834
投稿日: 2008/01/14(Mon) 22:19
投稿者Hongliang
ソースを見た限り問題なさそうです。

その上で、ちょっといじっていて気づいたことを書いておきます。画像処理については私も詳しくないので参考程度に。

RotateTrnasform や TranslateTransform は Transform プロパティに適用され、実際に描画されるときにはこの Matrix で各種変換が行われます。
で、180度回転を RotateTransform で与えた場合は Matrix の m12/m21 が「絶対値が極めて小さい値」に設定されますが、gif ファイルによってはこれらの値がある程度(ファイルによるみたい)より小さい絶対値をもつときにフレーム 0 の画像を描画しているようです。
ので、回避策の一つとしてこの値をある程度以上に設定する、というのが考えられます。がこの値を入れれば大丈夫ってのがあるのかないのかよく分からないので確実性に欠けますし、大きくしすぎると 180 度の回転に過不足が出てしまいます。
もう一つ、回避策として Bitmap.SetResolution の適用があります(原理はわかってません)。Bitmap インスタンスの生成後一度これを呼び出すと、上記 m12/m21 が最小値である 0 でも問題なく描画してくれるようになるみたいです。設定する値は、たぶん 96/96 固定でいいはずですが、ひょっとしたら画面解像度(画素数じゃなくて dpi 値。dpi スケールとか言うらしい)に合わせる必要があるかも知れません(96 dpi 環境以外は未確認)。

これ以外にも原因/回避法はあるかも知れませんが、一つの原因と回避法として。

[ツリー表示へ]