GIF画像表示の高速化

解決


カズ  2008-04-08 16:57:15  No: 139489  IP: 192.*.*.*

1GB以上あるTIFFファイルを細分化し、それを貼り合わせて見たい部分を表示するソフトを作ろうとしています。1000x1000程度に細分化された画像は当初BMPで保存していましたが色数も150程度に集約できるのでGIFに変換してみました。
表示する画面のサイズから2-4枚の分割画像を1枚1枚Loadして表示するPictureBoxに貼り付けるのですがBMPの時には(比較的)サクサク動いていたのがGIFにしてみたらモタツキが目立つようになりました。  コードとしては下記のようにPicture2に細分化した画像をロードしてPicture1に貼り付けるようにしています。  (W0,H0は固定サイズ)

Picture2.AutoSize = True
Picture2.Visible = False
Picture2.AutoRedraw = True

For i = 0 to 1
For j = 0 to 1
   sPicFile = Fnam & Trim(Str(i)) & Trim(Str(j)) & ".GIF" 'ファイル名を設定
   Picture2.picture = LoadPicture(sPicFile)
   W = Picture2.Width
   H = Picture2.Height
   X = X0 - W0
   Y = Y0 - H0
   Picture1.PaintPicture Picture2.Image,X, Y, W0, H0, 0, 0, W, H 'もしくはStretchBleで
Next j
Next i

のようにしています。BMPファイルであればまーまーのサクサク度ですがGIFだと遅いということはGIFのLoadに改善点が、また一度Picture2にロードしてからPicture1にCopyするということに無駄がある、など改善策があったら教えてください。  (VB6 SP6)

編集 削除
やじゅ  2008-04-08 20:52:02  No: 139490  IP: 192.*.*.*

そもそもGIFは遅いでしょ
色数も150程度に集約できるなら、BMP256でいいのでは?

編集 削除
カズ  2008-04-09 09:55:33  No: 139491  IP: 192.*.*.*

やじゅ様  ご回答をありがとうございます。

やはりGIFのLoadは遅く高速化の手段は特にないものと理解しました。ファイルサイズを取ってGIFにするか、高速化を取ってBMPにするか妥協点を見つけたいと思います。

また一旦Picture2にロードしてからPicture1にコピーするということに何か無駄がないか、もっと良い法方があるのではないかと期待しておりましたが特に問題はないようですのでとりあえずこれで進めてみます。  ありがとうございました。

編集 削除
魔界の仮面弁士  2008-04-09 18:31:01  No: 139492  IP: 192.*.*.*

> ファイルサイズを取ってGIFにするか、高速化を取ってBMPにするか

無圧縮ビットマップの代わりに、
RLE圧縮ビットマップを利用してみては如何でしょうか。

編集 削除
カズ  2008-04-10 16:50:18  No: 139493  IP: 192.*.*.*

魔界の仮面弁士様、RLEという耳寄りな情報をありがとうございます。
原理はhttp://www.ruche-home.net/program/bmp/rle.phpで見たところ白地の多い図版が多いので圧縮効果は大いに有効ではないかと期待できそうです。早速現在の画像をRLEにして試してみようとしたのですがBMPを読んでRLEで保存するソフトが当方にはないのでRLEファイルを探して(たった1枚見つけて)BMPに変換して比較して圧縮効果があることが確認できました。

VB6でRLEに変換するサンプルなどありましたらご紹介ください。よろしくお願いします。

編集 削除
K.J.K.  2008-04-11 15:50:22  No: 139494  IP: 192.*.*.*

解決済みなところですみませんが、今の普通のPCならば、GIFだから遅い、
ということはまず考えにくいのではないでしょうか。これがPNGやJPEGならば
確かに画像によってはBMPより体感できるほどはっきりと時間がかかることは
ありますが、GIFではそういう体験をここ10年以上した覚えがありません。

前回のEMFの描画でもそうなのですが、根本的に何か間違えているように
思えます。前回のときはEMFを描画するというコードが最後まで提示されて
いませんでしたし。

編集 削除
魔界の仮面弁士  2008-04-11 16:39:47  No: 139495  IP: 192.*.*.*

> GIFだから遅い、ということはまず考えにくいのではないでしょうか。
今回の投稿にあたり、連続して LoadPicture を繰り返すプログラムを書いて
試したのですが、当方環境では、かなりの速度低下がみられました。

一方、RLE 圧縮/非圧縮に関しては、ほとんど差がありませんでした。
(PNG, GIF に比べると、圧縮効率には難がありますけれども)


下記のコードで、当方では
  無圧縮圧縮BMP … 平均0.9秒弱
  RLE圧縮BMP … 平均0.9秒弱
  GIF89a … 平均13.8秒弱
という結果になりました。

なお、実験に使用した画像は、
http://dencha.ojaru.jp/programs_07/pg_graphic_04.html
の [gt_img_04_bmp_sample.zip] で提供されている
  rle8.bmp (227x149: 16,216バイト: RLE圧縮BMP)
  aaa8.bmp (227x149: 35,050バイト: BMP)
と、aaa8.bmp を Paint.NET で GIF89a 保存した物(9,570バイト)です。

Option Explicit

Private Sub Form_Load()
    Command1(0).Caption = "aaa8.bmp"
    Command1(1).Caption = "rle8.bmp"
    Command1(2).Caption = "gif8.gif"
End Sub

Private Sub Command1_Click(Index As Integer)
    Dim F As String
    F = "C:\RLE\" & Command1(Index).Caption
    Dim T As Single
    T = Timer
    Dim I As Integer
    For I = 1 To 1000
        Set Picture1.Picture = LoadPicture(F)
    Next
    Debug.Print Index, Timer - T
End Sub

編集 削除
K.J.K.  2008-04-11 18:23:16  No: 139496  IP: 192.*.*.*

確認してみました。確かにその画像だとDIB24に比べて14倍程度に遅くなりました。
DIB24は0.75秒に対して、GIFは10.7秒かかっています。(3回ずつの平均)
# GIFへの変換はImageMagickで減色->変換を行っています。

これから描画ルーチンを排除し、Picture型のオブジェクトに直接代入してみると、
DIB24で0.39秒、RLE4で0.20秒、RLE8で0.35秒、GIFで10.2秒になりました。
この場合は26倍程度になります。

で、壁紙なし設定のデスクトップ(1280x1024x2^32)をキャプチャしたものでも試してみました。普通に描画(Pictureプロパティに代入)する方です。
Iconは13x13配置できるうちの49個が配置してあります。
DIB24 24.3秒、GIF 90.1秒、JPEG 49.4秒
こちらでは4倍程度になっています。JPEGのが速いところが面白いですが。

これを、自作のGDI+にIPictureDispを被せたものに置き換えてみると、
DIB24、GIF、JPEG、PNGともにほぼ9秒前後(9.4、8.9、8.9、8.9)でした。
一応、JPEG < GIF < PNG < DIB24の順でした。ファイルサイズと同じ並びです。が、DIB24が0.5秒ほど遅かった以外はほとんど差はありませんでした。
http://www.koalanet.ne.jp/~akiya/vbtaste/vbp/GDIPP020.lzhの改良版。

ただ、そういうことを話の主体にしたいのではなく、折角TIFFで保持しているのならば、
専用のコンポーネントを用意するなどして、読み込み及び表示(描画)をその
コンポーネントに頼ってしまうのが無難なのではないか、
というのが私の意見です。

編集 削除
カズ  2008-04-12 12:12:50  No: 139497  IP: 192.*.*.*

魔界の仮面弁士様、K.J.K様、本格的なテストまでしていただき恐縮しています。ありがとうございました。当方ではRLEで描き込めるソフトがなかったためBMP2BMPというフリーソフトで同じBMP画像とRLEに変換した画像の圧縮率などを調べておりましたが余白の多いものでは1/20以下のファイルサイズになりました。一方込み入った画像ではBMPの元のサイズよりもRLEの方が大きくなって変換しないものもかなりありました。総体的には余白のあるものもかなりありますので良いとこ取りすればかなりのサイズ改善が期待できると思いました。

K.J.K様より大きなTIFFをそのまま処理するというアドバイスをいただきましたが当方のPC環境(メモリ=768MB)では1GB程度のTIFF画像(14270X26172ピクセル)であっても忘れた頃にロードが完了し、拡大や移動をしようとしても忘れた頃に動き出すという状況なので分割処理を考えたものです。これ以外に更に大きな画像もあると思いますので軽い画像にして処理したいと考えました。

以上から判断してとりあえずGIFで作業を続けバッチ処理によるRLE化が可能になった時点でRLE化していきたいと思います。色々とテストまでしていただき恐縮し、感謝いたします。ありがとうございました。

編集 削除