GdipCreateFromHDCを使用した際、
「480 AutoRedraw イメージを作成できません。」
というエラーが発生して、イメージの描画が行えない
こんばんは。
http://madia.world.coocan.jp/cgi-bin/VBBBS/wwwlng.cgi?print+200709/07090026.txt
http://madia.world.coocan.jp/cgi-bin/VBBBS/wwwlng.cgi?print+200710/07100010.txt
で質問させていただいた者です。
GDI+を使って、イメージファイルを開くユーザーコントロールを作成しています。
今回は、完成したユーザーコントロールの動作テストを行っていたときに、不可解なエラーが出てしまい
どうにも進めなくなったので お知恵を拝借したく書き込みさせていただきました。
イメージを開いた時に、ファイルの描画サイズ(容量ではなくサイズ)が一定以上のものだと
Err.Number : 480
Err.Description : AutoRedraw イメージを作成できません。
というエラーが発生して、描画処理が失敗します。
サイズが一定以下で普通に開けるものでも、描画時サイズを大きくして(拡大して)いくと、同様のエラーが出ます。
以下に、関係あると思われる部分のソースを挙げます
環境:
XP VB6SP6
GDI+ Type Library 1.31使用
gtypGPInput.GdiplusVersion = 1 で動作
描画の流れ
GDIスタート(GdiplusStartup)
ファイルイメージ取得(魔界弁士ロジック
イメージサイズ取得(GdipGetImageHeight、GdipGetImageWidth)
拡大時サイズ取得・変数に格納
コンテナオブジェクト(ピクチャボックス:UCImage)のサイズ変更
イメージ描画
イメージ描画の関数
Private Function UCSubDrawImage(Img As Long, ByVal lngImgWidth As Long, ByVal lngImgHeight As Long, _
Optional ByVal X As Long = 0, Optional ByVal Y As Long = 0, Optional Clear As Boolean = True) As GpStatus
'イメージ実描画 開始位置を指定することで二つのファイルを描画できる
Dim Graphics As Long
Dim ret As GpStatus
On Error GoTo UCSubDrawImageErr:
UCSubDrawImage = Ok
If Clear Then UCImage.Picture = LoadPicture("") '画面初期化
'PictureBoxのhDCからGraphicsオブジェクトの生成
ret = GdipCreateFromHDC(UCImage.hDC, Graphics) '*******←エラー発生
If (ret <> Ok) Then
UCSubDrawImage = ret
Err.Raise 1001, "GdipCreateFromHDC", "Graphicsを作成できません"
Exit Function
End If
ret = GdipSetInterpolationMode(Graphics, InterpolationModeDefault)
'描画
ret = GdipDrawImageRectI(Graphics, Img, X, Y, lngImgWidth, lngImgHeight)
If (ret <> GdiPlus.GpStatus.Ok) Then
UCSubDrawImage = ret
Err.Raise 1002, "GdipDrawImageRectI", "描画できません"
Exit Function
End If
'生成したオブジェクトの解放
ret = GdipDeleteGraphics(Graphics)
'表示画像の定着
UCImage.Refresh
Exit Function
UCSubDrawImageErr:
'最大サイズをオーバーした場合?
UCSubDrawImage = ValueOverflow
Debug.Print Err.Number & " " & Err.Description
'Call MsgBox(Err.Description & vbCrLf & lngImgHeight & " : " & lngImgWidth, , "UCSubDrawImage")
End Function
GdipCreateFromHDCは、戻り値を返さずにエラーを出すため、その下の
If (ret <> Ok) Then に処理が渡りません。
やむなくOn Errorで処理を飛ばして、ValueOverflowを返すようにしています。
GdipCreateFromHDC の時点でエラーが出るということは、コンテナオブジェクト(UCImage)のサイズが関係しているのかと思いますが、具体的にどんなサイズの時にエラーが出るのかがよくわかりません。
例えばこのエラーがGDI+の限界なのだとすれば、最大サイズの制限を設けてエラーを回避することもできますが、
そのサイズがどうなっているのかもよく分からない状態です。
実際に調べてみた所、
縦6800 横6800でエラー
縦6700 横6700 は正常
縦2820 横169200でエラー
縦2810 横168600は正常
という結果でした。
最初は縦*横のサイズで上限値が決まるのかと思っていましたが、この結果ですと
6800*6800 =46240000
2820*169200 =477144000
で、総ピクセル数には10倍近い差がでています。
手元のファイル描画ソフト「Susie」では、一辺32767ピクセルくらいまでは拡大できるようなので
それくらいで制御しようと考えていたのですが… 一辺6800ではいかにも不満です。
GDI+の限界であるなら仕方ないですけど 多分そんなことはないだろうと思うので
何か有効な対策をご存じの方がおりましたら(エラーが出る際の条件でも)、ご教授頂ければ幸いです。
それではよろしくお願いします。
これはGDI+とは関係のないVB6側の制限に引っかかっているからでしょう。
AutoRedrawプロパティをTrueにした場合、その大きさには「おそらく16bit OS
時代からの仕様」を引きずった制限があります。
で、描画はAutoRedraw=Trueに頼らないで行うのが無難かと。
K.J.K様
ご回答ありがとうございます。
VB6の制限となると回避のしようがないですね…
AutoRedrawを使用した描画を行っているのは、画像がフォームよりも大きかった場合に、ドラッグやスクロールバーで画像をスクロールさせるのを想定しているからなのですが(後は単純に楽だからですが)
これを使わずに描画を行うとなると 根本からの大改造が必要ですね…(涙
コンテナにピクチャボックスを使わなければいいのでしょうか…
またいろいろ調べてみます。
〜以下蛇足〜
今日、前回の書き込みを読み返してみたら 個人的なメモ書きがそのまま表示されていて血の気が引きました(修正できません
今度はもう少し落ち着いて書き込みします m(_ _)m
ツイート | ![]() |