投稿者 魔界の仮面弁士  (社会人) 投稿日時 2021/6/6 18:40:17
[2021/6/6 07:43:23]への返信
> 初期化とかが必要と書いて頂いてましたので、修正しました
GdipCreateBitmapFromFile が失敗したときにしか GdiplusShutdown が呼びだされておらず、
GdipCreateBitmapFromFile が失敗したときにも GdipGetImageWidth を呼んでいますね。

ActiveX の場合と違って、API 利用時は手順を間違えるとリソースリークに繋がるので、
 MsgBox "a1"
 MsgBox "a2"
などの異常系に到達した場合の流れもきちんと作りこみましょう。


> Private Type PICTDESC
提示頂いたコードでは未使用のようですが、もしかして、
OleCreatePictureIndirect API 等を使おうとしている?

あと、Long と LongPtr の使い分けに統一感が無いので、そこも整理した方が良さそうです。


> COLORが最初、マイナスになってしまいます。
GetPixel API は 24bit な色空間 (COLORREF)を返しますが、
GdipBitmapGetPixel は 32bit な色空間 (ARGB) を返すためです。

不透明度(Alpha) が &H00~&H7F の範囲ならば正数となり、
&H80~&HFF であれば負数になります。
完全不透明な色の場合、Alpha 値は FF です。

透明な背景を持つ Gif 画像の場合や、
半透明部を持つ Png 画像の場合は正数を返す可能性があります。


> R = Int(color / 256 / 256)
> G = Int(color / 256) Mod 256
> B = color Mod 256
もっと単純に「Int(color / 256 / 256)」→「color \ 256 \ 256」で良いと思います。

また、COLORREF は 24bit なので問題無いですが、
ARGB や OLE_COLOR などの 32bit にも対応させる場合は、こう書けます。
Dim c As Long
c = &H13579BDF

'上記を「&H13」「&H57」「&H9B」「&HDF」に分解する 
c0 = ((c And &HFF000000) \ &H1000000) And &HFF&
c1 = (c And &HFF0000) \ &H10000
c2 = (c And &HFF00&) \ &H100&
c3 = c And &HFF&

' OLE_COLOR … 00BBGGRR な 24bit 色(もしくは 800000nn で管理されるシステム色) 
' COLORREF  … 00RRGGBB な 24bit 色 
' ARGB      … AARRGGBB な 32bit 色 



> 'ここが良くわかりませんでした。 
> R = R + 256
> G = G + 256
> B = B + 256
> h = R * 256 * 256 + G * 256 + B
この h は何を求めるためのコードですか?



[2021/6/6 15:28:49]への返信
> Ret = GdipCreateBitmapFromHBITMAP(hBmp, 0&, GdipBmpHdl)
HBITMAP から GpBitmap に変換するまでは良いのですが、
その後、GdipDisposeImage で解放するのを忘れていますよ。
後始末はきちんと行いましょう。


> 色が4固定になってしまいます。・・

color 変数の宣言を忘れているのではありませんか?
変数宣言漏れの場合、たとえば
 MsgBox Color
という処理を書いた場合に、
 MsgBox stdole.LoadPictureConstants.Color
の意味になるので、おそらくこれが「4」の原因かと推察します。