環境はVB6(SP6)です
ずぶのど素人ですが宜しくお願いします。
以下でGDIリソースの減少の件で諦めて「解決」にしてしまいました。
タイトルを変えて再質問させて下さい。
http://madia.world.coocan.jp/cgi-bin/VBBBS2/wwwlng.cgi?print+200511/05110067.txt
通ってみたさんレス頂き済みませんでした。
ご指導頂いた方法(プログラムを2つに分けて運用する)を以下の様に解釈しまして試したのですが、
1.メインプログラム側からShell関数で引数を指定して、GDI処理用の別のプログラムを起動する。
2.Command関数でこの引数を取得して以下のGDI処理用のプロシージャ(ColorChange)を呼出して処理する。
3.GDI処理用プログラムを終了させる。
メイン側のPictureBox(以下のコードのPicSpliteです)の引渡し方と
受けてからの処理が解りません。
宜しければご指導お願いします。
Public Sub ColorChange(picSplite As PictureBox, selColor As String)
Dim i As Long
Dim j As Long
Dim R As Long
'ビット情報
Dim bp() As RGBQUAD 'ビットマップ操作
'線画部分を指定の色に置き換えて描画する
If selColor <> "白" Then
j = GetBitmapDataEs(picSplite, bp) 'ビットマップ情報取得(頂きものフリーソース)
End If
Select Case selColor
Case "赤"
For i = 0 To j
R = Int((CLng(bp(i).rgbRed) + CLng(bp(i).rgbGreen) + CLng(bp(i).rgbBlue)) / 3)
bp(i).rgbRed = 255
bp(i).rgbGreen = R
bp(i).rgbBlue = R
Next
Case "緑"
-----以下中略-----
-------------------
Case "白"
'白黒ネガ作成
With picSplite
BitBlt .hdc, 0, 0, .ScaleWidth, .ScaleHeight, .hdc, 0, 0, vbDstInvert
End With
End Select
If selColor <> "白" Then
SetBitmapDataEs picSplite, bp '指定色に変更する(頂きものフリーソース)
End If
End Sub
Shell関数でPictureBoxは渡せません。
EXEでなくActiveXなら渡せますがリソースが開放されるかは??です。
それより
GetBitmapDataEs
SetBitmapDataEs
を作り直すことを提案します。
同じPictureBoxだったらリソースを再利用するように
すればいいと思います。(クラス化とか)
これ以上はその関数が公開されてないので
アドバイスできません。
方向性を変えて…PictureBox の Link 系メソッドで画像を受け渡す、とか。
# リソースの件の解決策となるかどうかはわからないけど。
あんさん、Dentalさんご指導有難うございます。
あんさんへ
>Shell関数でPictureBoxは渡せません。
やはりアホな質問だった様ですね(_ _)
Webで検索しても出来そうな情報は見つからないので・・・納得しました。
>それより
>GetBitmapDataEs
>SetBitmapDataEs
>を作り直すことを提案します。
>同じPictureBoxだったらリソースを再利用するように
>すればいいと思います。(クラス化とか)
>これ以上はその関数が公開されてないので
>アドバイスできません。
著作者の使用条件に「改変・公開は禁止します」と有りますので残念ですが公開出来ません。
また、クラス化すること自体知識も経験も無いのでこれから勉強したいと思います。
Dentalさんへ
>方向性を変えて…PictureBox の Link 系メソッドで画像を受け渡す、とか。
># リソースの件の解決策となるかどうかはわからないけど。
「Link系メソッドで受け渡す」も初めて耳にする処理で、これから勉強したいと思います。
ど素人で、ご掲示の処理を実現するには時間(日数)を要します。
もう少しご教授頂いた事を理解出来るようになってから、また質問したいと思います。
あんさんにご指導頂いた、「GetBitmapDataEs」、「SetBitmapDataEs」を
クラス化するところまでは出来ました。
EXEにして試しましたがリソースの減少は変わりません。
クラス自体全く初めてのコーディングで以前JAVAのアプレットを自作(1回のみ)
した時と、ここ2日位にWebで勉強した知識だけで四苦八苦している状態です。
>同じPictureBoxだったらリソースを再利用するように
>すればいいと思います。(クラス化とか)
ご指摘の「リソースを再利用する」の方法が具体的に解りません。
コーディングしたクラスはクラスのモジュールレベルに
1.試用するGDI処理用APIの宣言
2.APIで試用する構造体、配列変数をPrivateで定義
Property Letプロシージャで「指定色="赤"などの文字列」の引数から
ビット情報の配列にセットする。
Functionプロシージャとして
GetBitmapDataEs」、「SetBitmapDataEs」を引数はPictureBoxのみにして
処理しています。
これを初回に掲載しましたColorChangeプロシージャから
コールする形にしています。
私のレベルで理解出来るかどうか判りませんが、今一度ご指導お願いします。
>GetBitmapDataEs」、「SetBitmapDataEs」を引数はPictureBoxのみにして
あれ
>著作者の使用条件に「改変・公開は禁止します」と有りますので残念ですが公開出来ません。
だったのでは?
あんさんレス有難うございます。
ご指摘の件について、自作のプログラムでの使用は構わないと有りますので
フリーソースは(標準モジュールに通常のコーディングされたもの)であり。
これをクラスに書き換えて、この一部を質問のため記載してしまいました。
やはりまずいのでしょうか?
http://madia.world.coocan.jp/cgi-bin/VBBBS2/wwwlng.cgi?print+200511/05110067.txt
でご指導頂いたことを参考にクラスについてもGDI処理についても全くの
初心者で無知など素人ですが、勉強しながら挑戦したいと思います。
また、ご指導を仰ぐことになると思います。
宜しくお願いします。
「フリーのソース」とやらを発見?
http://tokyo.cool.ne.jp/kanain/APIHTM/GetDIB.html
ということで、再確認。
このサンプルも、GDIリソースが減少し続けるということですか?
pushさんレス有難うございます
多分同じホームページです
http://tokyo.cool.ne.jp/kanain/SfDwLd.html
の「ビットマップ高速操作モジュール」BmpOP.lzhを利用させて頂いてます。
pushさんへ
>このサンプルも、GDIリソースが減少し続けるということですか?
私の利用の仕方の問題かもしれませんけど。
この関数を使用して、Visible=FalseにしたPictureBoxのフォアカラーを
連続して何回も呼出す処理をしています。
(この処理が根幹をなすプログラムです)
プログラムを終了すると起動前のGDIリソースまで回復します。
宜しくお願いします。
クラス化して呼ぶとき
>連続して何回も呼出す処理をしています
この処理の中でCreateDIBitmapを呼ばないように
してください。
EXEの中でCreateDIBitmapは一回だけ呼ぶことになります。
>> このサンプルも、GDIリソースが減少し続けるということですか?
この質問に対する明確な回答がありませんね。
…('A`)「生成-解放」といった、
「生まれて死ぬ」関係でラップできそうなのはクラスにするのが一番だと思うが…
※現在DIBを操作するクラスを作成中@Alphablend完成
VBもってないから
エクセルのVBAでサンプル動かそうと
してるけど
むずかしい・・挫折しそう・・
あんさん、pushuさん、ガッさんレス有難うございます。
留守にしていて返事が遅くなり済みませんでした。
あんさんへ
>EXEの中でCreateDIBitmapは一回だけ呼ぶことになります。
やはり私の使い方の問題の様ですね。
ただ現状はご指摘のことを実現するには、私のレベルではかなり難しいです。
時間掛けて取組んでみようと思います。
pushuさんへ
>この質問に対する明確な回答がありませんね
ど素人の私の利用の仕方の問題であろうと思います。
難しい事は解りません。
>ガッさんへ
クラスを勉強しながら、じっくり取り組みます。
色々質問し、ご指導の処理方法を実現出来る様に四苦八苦しています。
「著作権」の関係で問題が有るようですので、ソースを記載できず、回答者の方に
ご迷惑お掛けしているのではと心配しています。
現状をお伝えする為に、フリーのソースコード以外の関係する部分を以下に掲載
します。
ご指導下さった皆さん有難うございました。
現在はGDI処理部分をクラスモジュールに記述しています。
1.API関数用の構造体の定義
2.API関数の使用宣言
3.Private bp() As RGBQUAD 'ビットマップデータ
4.Private moPicBox As PictureBox '処理対象のPictureBox
5.フリーソースの二つの関数は、
1つのSUBプロシージャ(引数;flgGetSet as Boolean)に改変(違いは数行だけのため)
6.以下のフォームモジュールのColorChangeプロシージャから利用しています。
-----------------------------------------
(A)クラスモジュールの記述
-----------------------------------------
Property Set Device(PicBox As PictureBox)
'処理対象のPictureBoxをセットする
Set moPicBox = PicBox
With moPicBox
.ScaleMode = vbPixels
End With
End Property
Property Let BpLet(strColor As String)
Dim i As Long
Dim j As Long
Dim R As Long
'現在のビットマップ情報を配列に取得する
Call GetSetBitmapData(False)
j = UBound(bp())
'指定のカラー情報をビットマップ配列にセットする
Select Case strColor
Case "赤"
For i = 0 To j
R = Int((CLng(bp(i).rgbRed) + CLng(bp(i).rgbGreen) + CLng(bp(i).rgbBlue)) / 3)
bp(i).rgbRed = 255
bp(i).rgbGreen = R
bp(i).rgbBlue = R
Next
Case "緑"
For i = 0 To j
R = Int((CLng(bp(i).rgbRed) + CLng(bp(i).rgbGreen) + CLng(bp(i).rgbBlue)) / 3)
bp(i).rgbRed = R
bp(i).rgbGreen = 255
bp(i).rgbBlue = R
Next
Case "青"
For i = 0 To j
R = Int((CLng(bp(i).rgbRed) + CLng(bp(i).rgbGreen) + CLng(bp(i).rgbBlue)) / 3)
bp(i).rgbRed = R
bp(i).rgbGreen = R
bp(i).rgbBlue = 255
Next
Case "紫"
For i = 0 To j
R = Int((CLng(bp(i).rgbRed) + CLng(bp(i).rgbGreen) + CLng(bp(i).rgbBlue)) / 3)
bp(i).rgbRed = 255
bp(i).rgbGreen = R
bp(i).rgbBlue = 255
Next
Case "黄"
For i = 0 To j
R = Int((CLng(bp(i).rgbRed) + CLng(bp(i).rgbGreen) + CLng(bp(i).rgbBlue)) / 3)
bp(i).rgbRed = 255
bp(i).rgbGreen = 255
bp(i).rgbBlue = R
Next
Case "水"
For i = 0 To j
R = Int((CLng(bp(i).rgbRed) + CLng(bp(i).rgbGreen) + CLng(bp(i).rgbBlue)) / 3)
bp(i).rgbRed = R
bp(i).rgbGreen = 255
bp(i).rgbBlue = 255
Next
End Select
End Property
-----------------------------------------------
(B)以下はフォームモジュールのプロシージャです
-----------------------------------------------
Private Sub ColorChange(range As String, selColor As String)
Dim transColor As Long '透過色
Dim testBpOP As BmpOP
With picSprite
'スプライトのサイズを調整する
If range = "全体" Then
.Width = picSrc.Width
.Height = picSrc.Height
Else
.Width = srcRight - srcLeft
.Height = srcBottom - srcTop
End If
.BackColor = vbWhite
.Cls
'指定範囲をpicWhiteBlack(白黒図面)から背景色を透過にしてpicSpriteに転送する
transColor = picWhiteBlack.BackColor
TransparentBlt _
picSprite.hdc, 0, 0, srcRight - srcLeft, srcBottom - srcTop, _
picWhiteBlack.hdc, srcLeft, srcTop, srcRight - srcLeft, srcBottom - srcTop, transColor
End With
If selColor <> "白" Then
Set testBpOP = New BmpOP 'BmpOPクラスからtestBpOPオブジェクトを作成する
Set testBpOP.Device = picSprite 'プロパティーセット
End If
Select Case selColor
'クラスのProperty Letプロシージャで処理する
'picSpriteのビット情報をクラスの配列に取得する
Case "赤"
testBpOP.BpLet = "赤"
Case "緑"
testBpOP.BpLet = "緑"
Case "青"
testBpOP.BpLet = "青"
Case "紫"
testBpOP.BpLet = "紫"
Case "黄"
testBpOP.BpLet = "黄"
Case "水"
testBpOP.BpLet = "水"
Case "白"
'白黒ネガ作成
With picSprite
BitBlt .hdc, 0, 0, .ScaleWidth, .ScaleHeight, .hdc, 0, 0, vbDstInvert
End With
End Select
If selColor <> "白" Then
'線画部分(フォアカラー)を指定の色に置き換えて描画する
Call testBpOP.GetSetBitmapData(True)
End If
Set testBpOP = Nothing 'オブジェクトを解放する
End Sub
>Property Set Device(PicBox As PictureBox)
ここでCreateDIBitmapを呼んでください
ColorChangeも複数呼ばれているので
クラス化してください。
> Set testBpOP = New BmpOP 'BmpOPクラスからtestBpOPオブジェクトを作成する
> Set testBpOP.Device = picSprite 'プロパティーセット
こいうのはColorChangeを呼ぶ前に
実行してください
ColorChangeも同じクラスにしてもいいかも
イメージわきましたか?
>> この質問に対する明確な回答がありませんね
> ど素人の私の利用の仕方の問題であろうと思います。
> 難しい事は解りません。
利用の仕方を云々する前に、
フリーソースの二つの関数に問題が無いことを確認するのが先決でしょう。
なので、先ずそのサンプルを試して欲しかったのです。
問題無しとすれば、それ以外の所に問題在りということでしょう。
ところで、今回出てきたソースにTransparentBlt関数を使用していますね。
この関数、Win95系で使用すると、リソースを食いつぶすらしい?
試しに、この関数を使わないで、リソースを確認してみて下さい。
あんさん何度もご指導有難うございます。
ほぼ挫折して断念しかけていました(_ _)
私の現在のレベルでは極めて難題では有りますが
ご教授頂いた項目を1つづつやってみます。
>イメージわきましたか?
現在のやり方ではまずい事は理解できました。
解決への道標は良く解りました。
実現の目処は付きませんが頑張って見ます。
丁寧なご指導感謝しています。
有難うございます。
pushさんご指導有難うございます。
ご指摘の件につきまして
1.フリーソースの問題
プロの方が作成されたであろうソースに疑念を持つレベルに有りません。
サンプルコード自体をそのまま実行してもなんら問題有りません。
このサンプルソースをヒントに、今回のプログラムを思いつき、無知な素人が
自分のプログラムの都合に合わせた使い方をしている性と思っていました。
2.>TransparentBlt関数の件
環境はWindows98_SE、NEC-VALUSTAR VT667J/3FD RAM128MBです。
試してみます。
有難うございました。
pushさんへ
TransparentBlt関数の件
>試しに、この関数を使わないで、リソースを確認してみて下さい。
掲載しましたプロシージャ内及びこれを呼出す前段階のプロシージャ
及び他でも多用してますので明日以降に試してみます。
有難うございました。
pushさんへ
TransparentBlt関数の件
>試しに、この関数を使わないで、リソースを確認してみて下さい。
を試してみました。
同関数はソースファイル画像をオープンして作業用PictureBoxへの転送で2回、
背景色変更プロシージャで1回、
フォアカラー変更の前段回(掲載のColorChangeを呼ぶ直前)のプロシージャで2回、
掲載していますColorChangeプロシージャで1回
の合計6回使用していました。
1.これらの全てをとりあえず(’)にして実行、
2.その後、Bitblt()に変更して実行してみました。
1の場合当然画像が表示されませんがリソースの減少は無し
2の場合は当然ですが一時的に画像も表示され、リソースの減少は無し
GDIリソースの変化状況は、
パソコン起動後 95%
プログラム起動してフォーム表示で 92%
処理対象のソース画像ロード後 91%
その後はGDI処理の関係するメニューを何回繰返しても91%から変化しませんでした
プログラムを終了すると起動後の95%に戻りました。
>この関数、Win95系で使用すると、リソースを食いつぶすらしい?
私の環境はWindows98_SEですけど、
以上の結果からpushさんのご指摘通りと判断して良いでしょうか?
TransparentBlt関数に代わるものは有りますでしょうか?
プロの方の洞察力の深さに感嘆しました!
有難うございます。
ついでにもう少しご指導お願いします。
> TransparentBlt関数に代わるものは有りますでしょうか?
同等の機能を持つ関数を自作することになるでしょう。
例えば、こんな感じ。
http://www31.ocn.ne.jp/~heropa/vb19.htm
http://vbnet.mvps.org/index.html?code/bitmap/transparent.htm
pushさんへ
ご指導でGDIリソースの原因が判明し、その後Webで検索した情報から納得しました。
>同等の機能を持つ関数を自作することになるでしょう。
例えば、こんな感じ。
自作などとても無理ですが、ご紹介頂いたページで勉強します。
途中から変な質問のタイトルになりましたが、ど素人の質問に長い間回答を寄せて
頂いた皆さんに心より感謝します。
この質問で得た回答から短期間に有用な知識が得られました。
私のレベルでは原因が解っても解決には程遠いので、この辺で「解決」とさせて
頂きます。
また、宜しくお願いします、有難うございました。
ツイート | ![]() |