URLを指定してPNG画像を取り込む方法

解決


のんち  2005-09-15 10:11:04  No: 125344

VB6を使用しています。

URLを指定してPNG画像を取り込む方法を考えています。
現在は

URLDownloadToFile() で一旦ファイルに保存し、
GDI+ を利用してPictureBoxに貼り付けています。

ファイル保存する回数が多いので、ファイル保存せずに
取得する方法を探してます。
OleLoadPicturePath()も試したのですが、PNGは読み込めませんでした。
何か手があったら教えて下さい。

最終的には画像のピクセル単位のマトリックスが欲しいので、
PictureBoxに貼り付けているのですが、別にいい方法があったら
教えて下さい。

よろしくお願いします。


通ってみた  2005-09-15 10:32:10  No: 125345

どんな方法であれ、ダウンロードして表示するのには変わりないと思う
ファイルにするか、メモリに読み込んでそのまま表示するかの違いか・・・

表示するだけであれば、WebBrowserを使えば楽だよね

画像ファイルにNavigateするだけでいいから
ただ、
>>最終的には画像のピクセル単位のマトリックスが欲しい
が、どうなるか不明


のんち  2005-09-15 17:10:39  No: 125346

通ってみたさん ありがとうございます。

やりたいことは、以下の様にピクセル単位で色を取得して
加工したいのです。

Dim col(100,100) as long

For x = 0  To picbefore.ScaleWidth
    For y = 0 To picbefore.ScaleHeight
        col(x,y) = GetPixel(picbefore.hdc, intx, inty)
    Next
Next
If col(x,y) = vbWhite then co(x,y) = vbBlack

上記のようなことがしたいのですが、JPEGやBMPなどですと
URLを指定して直接PictureBoxに描画できるのですが、
PNGだと方法が見つからなかったので、一旦ファイルに保存して
GDI+で読み込んでいます。

colのテーブルが作成できれば、どんな方法でもいいのですが、
PictureBoxに貼り付ける方法しか考えつかなかったのです。
何かありましたらお願いします。


通ってみた  2005-09-15 18:16:01  No: 125347

まぁVB6.0ではBMP、GIF、Jpegが使えるので、それらは大丈夫でしょうけど、PNGはそのままじゃ使えませんからねぇ・・・

メモリに読み込んだ時点でPNGの圧縮を展開させながらPictureBoxへ書き込みできればファイルを介さなくてもできるでしょうが、それをやるとなるとPNGの仕様を理解して独自に展開させなければならないので、実現は難しいと思います


K.J.K.  2005-09-15 19:14:27  No: 125348

むかし実験で使ったサンプルで、問題は多々あるけれども、
http://www.koalanet.ne.jp/~akiya/vbtaste/vbp/PictView.lzh
こういうのでしょうか。

まぁ、もっとも、GDI+を使うのであれば、URLOpenBlockingStream
と組み合わせればそのままでできるでしょうが。


のんち  2005-09-15 21:29:01  No: 125349

通ってみたさん ありがとうございます。
K.J.K.さん ありがとうございます。
K.J.K.さんのソースはPNGファイルを読み込み、
PictureBoxへ表示するものでしょうか?
見た感じファイルを読み込みPictureBoxへ
表示するようですが

http://www.libpng.org/pub/png/img_png/pnglogo-blk-sml1.png
こういったURLを指定してPictureBoxへ表示
もしくは、上で書いたcolのテーブルができるものでしょうか?

質問ばかりですみません。よろしくお願いします。


のんち  2005-09-15 21:55:10  No: 125350

すみません、8:10頃の投稿はソースが変なので修正します。

Dim col(100,100) as long

For x = 0  To Picture1.ScaleWidth
    For y = 0 To Picture1.ScaleHeight
        col(x, y) = GetPixel(Picture1.hdc, x, y)
        if col(x, y) = vbWhite then col(x, y) = vbBlack
    Next
Next

ピクセル単位で色を取得して、その色を加工するということを
したいと思ってます。


GDI+  2005-09-16 21:02:47  No: 125351

> GDI+を使うのであれば、URLOpenBlockingStream
> と組み合わせればそのままでできるでしょうが。

という、有力回答をもらったんだから、GDI+も検討してみたら?
現状のGDI+ソースに少し手を入れればいいだけですよ。


のんち  2005-09-17 05:48:11  No: 125352

GDI+さん  するどい指摘ありがとうございました。
検索に没頭するあまり、URLOpenBlockingStream のことを
すっかり忘れていました。
URLOpenBlockingStream を使ってなんとか表示することができました。

以下ソースを貼りますので、怪しいところなどあったら
教えて下さい。

Option Explicit
Private Type tagPicBmp
    Size            As Long
    Type            As Long
    hBmp            As Long
    hPal            As Long
    Reserved        As Long
End Type

Private Type tagGUID
    Data1           As Long
    Data2           As Integer
    Data3           As Integer
    Data4(0 To 7)   As Byte
End Type
Private Declare Function GdipCreateBitmapFromStream Lib "gdiplus" ( _
        ByVal Stream As Long, bitmap As Long) As Long
Private Declare Function URLOpenBlockingStream Lib "urlmon" Alias "URLOpenBlockingStreamA" _
                                (ByVal pCaller As IUnknown, _
                                 ByVal szURL As String, _
                                 ppStream As Long, _
                                 ByVal dwResv As Long, _
                                 ByVal lpfnCB As IUnknown) As Long
Private Declare Function OleCreatePictureIndirect Lib "olepro32.dll" _
                                (lpPictDesc As tagPicBmp, _
                                 riid As tagGUID, _
                                 ByVal fPictureOwnsHandle As Long, _
                                 ipic As IPicture) As Long
Private Declare Function LoadImage Lib "user32" Alias "LoadImageA" _
                                (ByVal hInst As Long, _
                                 ByVal lpszName As Long, _
                                 ByVal uType As Long, _
                                 ByVal cxDesired As Long, _
                                 ByVal cyDesired As Long, _
                                 ByVal fuLoad As Long) As Long
                                 Private Type GdiplusStartupInput
    GdiplusVersion              As Long
    DebugEventCallback          As Long
    SuppressBackgroundThread    As Long
    SuppressExternalCodecs      As Long
End Type
Private Declare Function GdiplusStartup Lib "gdiplus" _
                                (ByRef token As Long, _
                                 ByRef inputbuf As GdiplusStartupInput, _
                                 ByRef outputbuf As Long) As Long
Private Declare Function GdiplusShutdown Lib "gdiplus" _
                                (ByVal token As Long) As Long

Private Declare Function GdipCreateBitmapFromFile Lib "gdiplus" _
                                (ByVal filename As Long, _
                                 ByRef bitmap As Long) As Long
Private Declare Function GdipCreateHBITMAPFromBitmap Lib "gdiplus" _
                                (ByVal bitmap As Long, _
                                 ByRef hbmReturn As Long, _
                                 ByVal background As Long) As Long
Private Declare Function GdipDisposeImage Lib "gdiplus" _
                                (ByVal image As Long) As Long

Public Function URLLoadPNGPicture(ByVal strFileName As String) As Picture
    Dim gsi As GdiplusStartupInput
    Dim rslt As Long
    Dim lngGdiPlusTolen As Long
    Dim lngBitmap As Long
    Dim hBitmap As Long

    ' 構造体初期化
    With gsi
        .GdiplusVersion = 1
        .DebugEventCallback = 0
        .SuppressBackgroundThread = 0
        .SuppressExternalCodecs = 0
    End With

    'GDI+初期化
    Dim oStream As Long
    rslt = GdiplusStartup(lngGdiPlusTolen, gsi, 0)
    If rslt = 0 Then
        'イメージファイルの読み込み
        rslt = URLOpenBlockingStream(Nothing, strFileName, oStream, 0, Nothing)
        If rslt = 0 Then
            'GDIビットマップを作成する。
            rslt = GdipCreateBitmapFromStream(oStream, lngBitmap)
            If rslt = 0 Then
                'GDIビットマップハンドルを作成する。
                rslt = GdipCreateHBITMAPFromBitmap(lngBitmap, hBitmap, 0)
            
                'ピクチャーオブジェクトに変換する処理。
                Set URLLoadPNGPicture = ConvertBitmap(hBitmap)
            
                '取得したイメージを開放する。
                Call GdipDisposeImage(lngBitmap)
            End If
        End If
        Call GdiplusShutdown(lngGdiPlusTolen)
    End If
    If rslt Then Err.Raise 481, , "エラー"
End Function

Private Sub Command1_Click()
    Dim urlName As String
    
    urlName = "http://www.libpng.org/pub/png/img_png/pnglogo-blk-sml1.png"
    Picture1.BorderStyle = 0    ' なし
    Picture1.AutoRedraw = True
    Set Picture1.Picture = URLLoadPNGPicture(urlName)

Exit Sub

通ってみたさん K.J.K.さん GDI+さん  ありがとうございました。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加