|
|
|
2022/7/13(Wed) 09:30:33|NO.96797
Susieを使用してPNGなどの画像からアルファチャンネルのみをロードしたいのですが、
どこをどのように弄れば出来るのかが分かりません。
少し変えるだけで可能でしょうか?分かる方がいらっしゃれば教えていただきたいです。
個人的に
if spi_IsSupported(hModule.cnt, fn, varptr(filebuffer)+128) {
となってるところが気になるのですが、+128...これが何の役割を果たすのかも理解できずにいます...
以下のスクリプトは「 https://tu3.jp/0228」につーさ様が公開していたものです。
#module
#uselib "kernel32.dll"
#cfunc LoadLibrary "LoadLibraryA" sptr
#cfunc GetProcAddr "GetProcAddress" int,sptr
#cfunc LocalLock "LocalLock" int
#func LocalUnlock "LocalUnlock" int
#func LocalFree "LocalFree" int
#func VirtualProtect "VirtualProtect" var, int, int, var
#define mdim(%1,%2)dim %1,%2 :VirtualProtect %1,(%2)*4,$40,AZSD
#uselib "gdi32.dll"
#func SetDIBitsToDevice "SetDIBitsToDevice" \
int,int,int,int,int,int,int,int,int,int,int,int
#deffunc GetBmpSize str fn, array val_sz, local bmpsz
bmpsz = 0,0,0
bload fn,bmpsz, 12,14
if bmpsz = 40 : val_sz = bmpsz.1, bmpsz.2 : return 0
if bmpsz = 12 : val_sz = wpeek(bmpsz,4), wpeek(bmpsz,6) : return 1
return -1
;// 初期化
#deffunc _spi_init
LoadedPlugins = 0
mdim cbfunc,2
cbfunc = 0x0CC2C033,0x00000000 ;// xor eax,eax : ret 12
pfnCallback = varptr(cbfunc)
return
;// 単一DLL読み込み
#deffunc spi_Load str _dllname, local hDll ,\
local pfn, local prm, local ret
hDll = LoadLibrary(_dllname)
if hDll = 0 : return -1 ;// Load失敗
pfn = GetProcAddr(hDll,"GetPluginInfo")
if pfn = 0 : return -2 ;// susie pluginじゃない
sdim buf,256
prm = 0,varptr(buf), 256
ret = callfunc(prm,pfn,3)
;// 4E493030 = '00IN' 画像読み込みプラグインじゃない
if lpeek(buf,0) != 0x4E493030 : return -3
hModule.LoadedPlugins = hDll
LoadedPlugins++
return 0
;// フォルダ内DLL全読み込み
#deffunc spi_LoadAll str _dlldir ,local curdir, local rdptr, local list, local dllfn
curdir = dir_cur : chdir _dlldir
rdptr = 0
dirlist list, "*.spi"
repeat stat
getstr dllfn,list,rdptr : rdptr += strsize
spi_Load dllfn
loop
chdir curdir
return LoadedPlugins
#defcfunc spi_IsSupported int _hModule, str _filename, int _dw, local fn, \
local pfn, local prm, local ret
fn = _filename
pfn = GetProcAddr(_hModule,"IsSupported")
if pfn = 0 : return 0
prm = varptr(fn), _dw
return callfunc(prm,pfn,2)
#deffunc spi_GetPicture int _hModule, int _buf, int _len, int _mode ,\
local pfn, local prm, local ret
pfn = GetProcAddr(_hModule,"GetPicture")
;LPSTR buf, long len, unsigned int 1, HANDLE *pHBInfo, HANDLE *pHBm, pfnCallback, 0
prm = _buf, _len, 1, varptr(HBi), varptr(HBm), pfnCallback, 0
ret = callfunc(prm,pfn,7)
if ret ! 0 : return ret
pbi = LocalLock(HBi)
pbm = LocalLock(HBm)
dupptr bi,pbi+4,8,vartype("int")
w = bi.0
h = bi.1
curgsel = ginfo_sel
repeat 1
if _mode ! 0 : break
mref bmscr,67 ;// ぷましゃんスクリを参考にしてみた
if bmscr.17=1 : buffer ginfo_sel, w, h : break
if bmscr.17=2 : screen ginfo_sel, w, h, bmscr.19&$ffff<<1 : break
bgscr ginfo_sel, w, h, 0
loop
SetDIBitsToDevice hdc,ginfo_cx,ginfo_cy,w,h,0,0,0,h,pbm,pbi,0
redraw
LocalUnlock HBi
LocalUnlock HBm
LocalFree HBi
LocalFree HBm
return 0
;// 画像ロード ファイル名, picload モード
;// ……とてつもなく中途半端
#deffunc spi_Picload str _fn, int _mode, local fn ,\
local pfn, local prm, local ret
fn = _fn
exist fn : if strsize = -1 : return -1 : else : sz = strsize
; if getpath(fn,18)=".bmp" : picload fn,_mode : return 0
ret = -2
sdim filebuffer,sz
bload fn,filebuffer
repeat LoadedPlugins
if spi_IsSupported(hModule.cnt, fn, varptr(filebuffer)) {
spi_GetPicture hModule.cnt, varptr(filebuffer), sz, _mode
if stat = 0 { ret = 0 : break }
}
if spi_IsSupported(hModule.cnt, fn, varptr(filebuffer)+128) {
spi_GetPicture hModule.cnt, varptr(filebuffer)+128, sz-128, _mode
if stat = 0 { ret = 0 : break }
}
loop
return ret
#global
_spi_init
//////////////////////////////////////////////////
spi_LoadAll dir_cur ;// フォルダ内のspi全読み込み
onclick gosub *load
stop
*load
dialog"",16
dir=getpath(refstr,32)
file=getpath(refstr,3+8)
chdir dir
spi_Picload file,1;// 画像ロード
;// stat=0なら成功、-1ならファイルが見つからない、-2はそれ以外のエラー
return
| |
|
2022/7/13(Wed) 20:38:29|NO.96801
> varptr(filebuffer)
これは変数 filebuffer のポインタを取得という意味ですから
+128はそのポインタから+128バイト(ヘッダ?)先を示していると思われます。
固定長ヘッダならこれでいいかもしれませんが、固定長なんでしょうか?
pngについて調べたほうがよさそうです。
参考
PNG ファイルフォーマット
https://www.setsuki.com/hsp/ext/png.htm
|
|
2022/7/13(Wed) 21:37:51|NO.96802
Susieプラグインは過去に実験的に弄ったことがある程度なので
間違っていたら申し訳ないのですが、私が検証してみた限り、
・DLL Export Viewerを使ってIFPNG.SPIに内蔵されている関数を調べても、
Susieプラグインの標準的なAPIしかなく、pngならではのものは無かった。
・spi_GetPicture内で使われているBITMAPINFOHEADERのbiBitCountを見ても24で
(R・G・Bがそれぞれ8bitで合計24bit)、透過色に関する情報は無い様子。
・ConfigurationDlgで設定ダイアログを表示する、というのもやってみたが、
見た感じどうも「特定の背景色に透過情報ありの画像データを合成する」という
作業をIFPNG.SPI自身が自動的に行ってしまうようで、
透過情報を抜き出すことはできない模様?
というわけで、私が調べた限りでは、どうやらSusieプラグインを使って
pngの透過情報を抜き出すことはできない様子です。
Artlet2Dを使えばpngの透過情報は抜き出せると思いますが、
Susieプラグインでなければいけない理由があるのでしょうか?
(以下、Artlet2Dを使った場合)
#include "a2d.hsp"
dir=dir_cur
dialog "*.*",16
if stat=0 : end
chdir dir
alCreateImageByFile 0,refstr : alSelectImage 0
w=alGetWidth() : h=alGetHeight()
screen 0,w,h
ddim mat,20
mat(MAT_R)=0.0, 0.0, 0.0, 1.0, 0.0
mat(MAT_G)=0.0, 0.0, 0.0, 1.0, 0.0
mat(MAT_B)=0.0, 0.0, 0.0, 1.0, 0.0
mat(MAT_A)=0.0, 0.0, 0.0, 0.0, 1.0
alCopyModeColorMatrix mat
alCopyImageToScreen 0,0,0,0,w,h,0,0
redraw 1
>+128...これが何の役割を果たすのかも理解できずにいます
Macバイナリ対策のようです。
まずMacバイナリが無いものとして、ロードしたファイルが
Susieプラグインで扱える画像ファイルなのかどうかをチェックし、
その後にMacバイナリがあるものとして同じことを繰り返しているという
流れです。
| |
|
2022/7/14(Thu) 09:43:32|NO.96803
窓月らら様、沢渡様、ご回答ありがとうございます。
+128は自分も画像の形式に関連するヘッダの先を示しているかと思っていたのですが、
Macバイナリというものがあるのは初めて知りました。
Susieプラグインを詳しく調べていただきありがとうございます。
とても勉強になりました。
>Artlet2Dを使えばpngの透過情報は抜き出せると思いますが、
>Susieプラグインでなければいけない理由があるのでしょうか?
Susieを使う理由は、自分で試した限りでは他のどの方法よりも高速に画像を読み込めるようだったからです。
作っているソフトの都合上、透過情報のみを抜き出す必要があり、今はimgctl.dllを使って抜き出しています。
Artlet2Dでも良いのですが、解像度が高い画像だとどうしても速度が遅くなってしまうのです...(imgctlでもやや遅いですが)
事前に書いておくべきでした。失礼しました。
現状維持しながら他にもっと高速な方法が無いか調べてみます。
|
|
2022/7/14(Thu) 16:49:54|NO.96805
Artlet2Dの中身ってgdiだと思うので、そこまで遅くないような気がしていて、
hamさんのホームページにあるようなデスクトップマスコットのような使い方であれば、
おそらく、透明情報だけを抜き出して何かしらレイヤーウインドウに設定するのに速度が遅くなっている様な気がしまして、
アルファ付きのバッファをそのまま使ったらダメですかね。私の環境だと以下の例で一瞬で表示されます。
※画像ドロップ:開く、ESC:終了
※あとSusieは24bitみたいで、きれいなアルファ抜きは出来ないですね。(内部で背景色に合成される)
もし何かのライブラリを利用されるなら32bitのDIBを返すプラグインを探されるのが良いかと思います。
;-------------------------------------------------
#module LAYERED_WINDOW
#uselib "gdi32.dll"
#cfunc CreateCompatibleDC "CreateCompatibleDC" sptr
#func DeleteDC "DeleteDC" sptr
#cfunc CreateCompatibleBitmap "CreateCompatibleBitmap" sptr,sptr,sptr
#func SelectObject "SelectObject" sptr,sptr
#func DeleteObject "DeleteObject" sptr
#func StretchDIBits "StretchDIBits" sptr,sptr,sptr,sptr,sptr,sptr,sptr,sptr,sptr,sptr,sptr,sptr,sptr
#define SRCCOPY 0x00CC0020
#define CAPTUREBLT 0x40000000
#uselib "user32.dll"
#cfunc GetWindowLongA "GetWindowLongA" sptr,sptr
#func SetWindowLongA "SetWindowLongA" sptr,sptr,sptr
#define GWL_STYLE -16
#define GWL_EXSTYLE -20
#define WS_EX_LAYERED 0x00080000
#func UpdateLayeredWindow "UpdateLayeredWindow" sptr,sptr,sptr,sptr,sptr,sptr,sptr,sptr,sptr
#define ULW_COLORKEY 0x00000001
#define ULW_ALPHA 0x00000002
#define ULW_OPAQUE 0x00000004
#define ULW_EX_NORESIZE 0x00000008
#cfunc GetDC "GetDC" sptr
#func ReleaseDC "ReleaseDC" sptr,sptr
#define ctype BLEND_FUNCTION(%1=0,%2=0,%3=255,%4=1) (((%4&0xFF)<<24)|((%3&0xFF)<<16)|((%2&0xFF)<<8)|(%1&0xFF))
#define AC_SRC_OVER 0x00
#define AC_SRC_ALPHA 0x01
#deffunc lwAlpha var bmp, int alpha
_hdc = GetDC(hwnd)
hsrcdc = CreateCompatibleDC(_hdc)
hbitmap = CreateCompatibleBitmap(_hdc, ginfo_sx, ginfo_sy)
ReleaseDC hwnd, _hdc
SelectObject hsrcdc, hbitmap
bmpinfo = 40, ginfo_sx, ginfo_sy, 0x200001, 0
; StretchDIBits hsrcdc, 0,0,ginfo_sx, ginfo_sy, 0,0,ginfo_sx, ginfo_sy, varptr(bmp), varptr(bmpinfo), DIB_RGB_COLORS, SRCCOPY|CAPTUREBLT
StretchDIBits hsrcdc, 0,0,ginfo_sx, ginfo_sy, 0,ginfo_sy,ginfo_sx, -ginfo_sy, varptr(bmp), varptr(bmpinfo), DIB_RGB_COLORS, SRCCOPY|CAPTUREBLT; 上下反転が必要な場合
wpt = ginfo_wx1, ginfo_wy1 : wsize = ginfo_sx, ginfo_sy : pt = 0, 0
blend = BLEND_FUNCTION(AC_SRC_OVER, 0, alpha, AC_SRC_ALPHA)
SetWindowLongA hwnd, GWL_EXSTYLE, GetWindowLongA(hwnd, GWL_EXSTYLE) | WS_EX_LAYERED
UpdateLayeredWindow hwnd, hdc, varptr(wpt), varptr(wsize), hsrcdc, varptr(pt), 0, varptr(blend), ULW_ALPHA
DeleteObject hbitmap
DeleteDC hsrcdc
return
#global
;------------------------------------------------
#include "a2d.hsp"
#uselib "shell32.dll"
#func DragAcceptFiles "DragAcceptFiles" sptr,sptr
#func DragQueryFile "DragQueryFileA" sptr,sptr,sptr,sptr
#func DragFinish "DragFinish" sptr
DragAcceptFiles hwnd, 1
oncmd gosub *WM_DROPFILES, 0x0233
oncmd gosub *WM_LBUTTONDOWN, 0x0201
onkey gosub *ON_KEY
stop
*WM_DROPFILES
hDrop = wParam : sdim file, 260 : DragQueryFile hDrop, 0, varptr(file), 260 : DragFinish hDrop
alCreateImageByFile 0,file : if stat != 0 : return
screen 0,alGetWidth(),alGetHeight(),screen_hide : DragAcceptFiles hwnd, 1
;--------------------------
alGetBitmapVData _size, _bitmap ; alpha付きbitmap取得
lwAlpha _bitmap, 255 ; ←追加した命令
;--------------------------
gsel 0,2 : redraw 1
return
*WM_LBUTTONDOWN
gsel ginfo_intid
sendmsg hwnd , 0x00a1 , 0x02 , lparam
return
*ON_KEY
if iparam = 27 : end
return
| |
|
2022/7/15(Fri) 09:23:17|NO.96808
usagi様、ご回答ありがとうございます。
Artlet2Dでも32bitのDIBのまま処理するとこんなにも高速になるのですね。
お察しの通り、今までHSPの通常のウィンドウに描画してから処理していたのですが、それが非常に遅いのですね。
Susieが高速だったのは、元々24bit故に24bitへの変換が必要なかったからでしょうかね?
今の自分の知識で上手く扱えるかどうか少し不安ですが、有難く使わせていただきます!
|
|
2022/7/16(Sat) 05:34:12|NO.96810
おぉ、すみません。MSDNの説明みたらアルファ値を事前乗算してくれとありましたね。
https://docs.microsoft.com/en-us/windows/win32/api/wingdi/ns-wingdi-blendfunction
"the red, green and blue channel values in the bitmap must be premultiplied"
もしかしたら遅いと仰られていた原因がコレなのかもですね。(HSPで事前乗算すると結構時間かかるので)
この部分だけCでやった方が良いのかもしれませんが、Artlet2Dでこのまま作ってみました。
どう早くするかは時間のある時に考えてみますが、取り急ぎ正しく表示されると思いますのでどうぞ。
;================================================
#module LAYERED_WINDOW
; gdi32 ---------------------
#uselib "gdi32.dll"
#func CreateDIBSection "CreateDIBSection" sptr,sptr,sptr,sptr,sptr,sptr
#cfunc CreateCompatibleDC "CreateCompatibleDC" sptr
#func DeleteDC "DeleteDC" sptr
#cfunc CreateCompatibleBitmap "CreateCompatibleBitmap" sptr,sptr,sptr
#func SelectObject "SelectObject" sptr,sptr
#func DeleteObject "DeleteObject" sptr
#func StretchDIBits "StretchDIBits" sptr,sptr,sptr,sptr,sptr,sptr,sptr,sptr,sptr,sptr,sptr,sptr,sptr
#define SRCCOPY 0x00CC0020
#define CAPTUREBLT 0x40000000
; user32 --------------------
#uselib "user32.dll"
#cfunc GetWindowLongA "GetWindowLongA" sptr,sptr
#func SetWindowLongA "SetWindowLongA" sptr,sptr,sptr
#func UpdateLayeredWindow "UpdateLayeredWindow" sptr,sptr,sptr,sptr,sptr,sptr,sptr,sptr,sptr
#cfunc GetDC "GetDC" sptr
#func ReleaseDC "ReleaseDC" sptr,sptr
#define GWL_STYLE -16
#define GWL_EXSTYLE -20
#define WS_EX_LAYERED 0x00080000
#define ULW_COLORKEY 0x00000001
#define ULW_ALPHA 0x00000002
;#define ctype BLEND_FUNCTION(%1=255) (0x01000000|((%1&0xFF)<<16))
#define ctype BLEND_FUNCTION(%1=255) (0x01000104|((%1&0xFF)<<16))
; function ------------------
#deffunc lwAlpha var bmp, int alpha
bmpinfo = 40, ginfo_sx, ginfo_sy, 1|(32<<16), 0 ,0,0,0,0,0
hdcDst = GetDC(0)
hsrcdc = CreateCompatibleDC(hdcDst)
hbitmap = CreateCompatibleBitmap(hdcDst, ginfo_sx, ginfo_sy)
SelectObject hsrcdc, hbitmap
StretchDIBits hsrcdc, 0,0,ginfo_sx,ginfo_sy, 0,ginfo_sy,ginfo_sx,-ginfo_sy, varptr(bmp), varptr(bmpinfo), 0, SRCCOPY|CAPTUREBLT
SetWindowLongA hwnd, GWL_EXSTYLE, GetWindowLongA(hwnd, GWL_EXSTYLE) | WS_EX_LAYERED
ptDst = ginfo_wx1, ginfo_wy1
size = ginfo_sx, ginfo_sy
ptSrc = 0, 0
blend = BLEND_FUNCTION(alpha)
crKey = 0
dwFlags = ULW_ALPHA
UpdateLayeredWindow hwnd, hdcDst, varptr(ptDist), varptr(size), hsrcdc, varptr(ptSrc), crKey, varptr(blend), dwFlags
ReleaseDC 0, hdcDst
DeleteObject hbitmap
DeleteDC hsrcdc
return
#global
;================================================
#include "a2d.hsp"
#uselib "shell32.dll"
#func DragAcceptFiles "DragAcceptFiles" sptr,sptr
#func DragQueryFile "DragQueryFileA" sptr,sptr,sptr,sptr
#func DragFinish "DragFinish" sptr
DragAcceptFiles hwnd, 1
oncmd gosub *WM_DROPFILES, 0x0233
oncmd gosub *WM_LBUTTONDOWN, 0x0201
onkey gosub *ON_KEY
stop
*WM_DROPFILES
hDrop = wParam : sdim file, 260 : DragQueryFile hDrop, 0, varptr(file), 260 : DragFinish hDrop
alCreateImageByFile 0,file : if stat != 0 : return
screen 0,alGetWidth(),alGetHeight(),screen_hide : DragAcceptFiles hwnd, 1
; ※追加 事前乗算 ※※※※※※※※
alCreateImage 1, alGetWidth(), alGetHeight()
alColor: alFillRect : alCopyImageToImage 0,1
alSelectImage 0 : alGetBitmapVData _size, _bitmap ; alpha付きbitmap取得
alSelectImage 1 : alGetBitmapVData _size, _bitmapm ; alpha事前乗算済bitmap取得
repeat length(_bitmap)
_bitmap(cnt) = (_bitmap(cnt)&0xFF000000) | (_bitmapm(cnt)&0x00FFFFFF)
loop
;※※※※※※※※※※※※※※※※※
lwAlpha _bitmap, 255 ; ←追加した命令
gsel 0,2 : redraw 1
return
*WM_LBUTTONDOWN
gsel ginfo_intid
sendmsg hwnd , 0x00a1 , 0x02 , lparam
return
*ON_KEY
if iparam = 27 : end
return
| |
|
2022/7/16(Sat) 06:05:35|NO.96811
あっ、hamさんが作られてるソフトの方が断然読み込み早いです。(気合入ってますね。)
愚直なループ部分を何んとかしないとダメですね。
|
|
2022/7/16(Sat) 06:25:25|NO.96812
a2d.hsp の alGetBitmapVData命令内では PixelFormat32bppARGB を指定してピクセルデータを取得しているのですが、PixelFormat32bppPARGB を指定するとアルファ値が事前乗算されたデータを取得することができます。
ということで、a2d.hsp を少し拡張しました。
;-------------------------------------------------
#module LAYERED_WINDOW
#uselib "gdi32.dll"
#cfunc CreateCompatibleDC "CreateCompatibleDC" sptr
#func DeleteDC "DeleteDC" sptr
#cfunc CreateCompatibleBitmap "CreateCompatibleBitmap" sptr,sptr,sptr
#func SelectObject "SelectObject" sptr,sptr
#func DeleteObject "DeleteObject" sptr
#func StretchDIBits "StretchDIBits" sptr,sptr,sptr,sptr,sptr,sptr,sptr,sptr,sptr,sptr,sptr,sptr,sptr
#define SRCCOPY 0x00CC0020
#define CAPTUREBLT 0x40000000
#uselib "user32.dll"
#cfunc GetWindowLongA "GetWindowLongA" sptr,sptr
#func SetWindowLongA "SetWindowLongA" sptr,sptr,sptr
#define GWL_STYLE -16
#define GWL_EXSTYLE -20
#define WS_EX_LAYERED 0x00080000
#func UpdateLayeredWindow "UpdateLayeredWindow" sptr,sptr,sptr,sptr,sptr,sptr,sptr,sptr,sptr
#define ULW_COLORKEY 0x00000001
#define ULW_ALPHA 0x00000002
#define ULW_OPAQUE 0x00000004
#define ULW_EX_NORESIZE 0x00000008
#cfunc GetDC "GetDC" sptr
#func ReleaseDC "ReleaseDC" sptr,sptr
#define ctype BLEND_FUNCTION(%1=0,%2=0,%3=255,%4=1) (((%4&0xFF)<<24)|((%3&0xFF)<<16)|((%2&0xFF)<<8)|(%1&0xFF))
#define AC_SRC_OVER 0x00
#define AC_SRC_ALPHA 0x01
#deffunc lwAlpha var bmp, int alpha
_hdc = GetDC(hwnd)
hsrcdc = CreateCompatibleDC(_hdc)
hbitmap = CreateCompatibleBitmap(_hdc, ginfo_sx, ginfo_sy)
ReleaseDC hwnd, _hdc
SelectObject hsrcdc, hbitmap
bmpinfo = 40, ginfo_sx, ginfo_sy, 0x200001, 0
; StretchDIBits hsrcdc, 0,0,ginfo_sx, ginfo_sy, 0,0,ginfo_sx, ginfo_sy, varptr(bmp), varptr(bmpinfo), DIB_RGB_COLORS, SRCCOPY|CAPTUREBLT
StretchDIBits hsrcdc, 0,0,ginfo_sx, ginfo_sy, 0,ginfo_sy,ginfo_sx, -ginfo_sy, varptr(bmp), varptr(bmpinfo), DIB_RGB_COLORS, SRCCOPY|CAPTUREBLT; 上下反転が必要な場合
wpt = ginfo_wx1, ginfo_wy1 : wsize = ginfo_sx, ginfo_sy : pt = 0, 0
blend = BLEND_FUNCTION(AC_SRC_OVER, 0, alpha, AC_SRC_ALPHA)
SetWindowLongA hwnd, GWL_EXSTYLE, GetWindowLongA(hwnd, GWL_EXSTYLE) | WS_EX_LAYERED
UpdateLayeredWindow hwnd, hdc, varptr(wpt), varptr(wsize), hsrcdc, varptr(pt), 0, varptr(blend), ULW_ALPHA
DeleteObject hbitmap
DeleteDC hsrcdc
return
#global
;------------------------------------------------
#include "a2d.hsp"
;-- a2d.hsp を拡張 ------------------------------
#module a2dp
#const PixelFormat32bppPARGB $E200B
#deffunc alGetBitmapPVData_start var ps, var pv ; size, vvar
if imgValid@a2d {
; LockBits して bitmap image へのポインタを得る
rect@a2d = 0, 0, imgWidth@a2d, imgHeight@a2d
dim BitmapData@a2d, 8
GdipBitmapLockBits@a2d imgImage@a2d, varptr(rect@a2d), 1, PixelFormat32bppPARGB, varptr(BitmapData@a2d)
;GdipBitmapUnlockBits@a2d imgImage@a2d, varptr(BitmapData@a2d)
ps = BitmapData@a2d(0) * BitmapData@a2d(1) * 4 ; Width * Height * ByPP
dupptr pv, BitmapData@a2d(4), ps
;ロックしたままにして
return 0
}
return -1
#deffunc alGetBitmapPVData_end
if imgValid@a2d {
GdipBitmapUnlockBits@a2d imgImage@a2d, varptr(BitmapData@a2d)
;アンロック
return 0
}
return -1
#global
;------------------------------------------------
#uselib "shell32.dll"
#func DragAcceptFiles "DragAcceptFiles" sptr,sptr
#func DragQueryFile "DragQueryFileA" sptr,sptr,sptr,sptr
#func DragFinish "DragFinish" sptr
DragAcceptFiles hwnd, 1
oncmd gosub *WM_DROPFILES, 0x0233
oncmd gosub *WM_LBUTTONDOWN, 0x0201
onkey gosub *ON_KEY
stop
*WM_DROPFILES
hDrop = wParam : sdim file, 260 : DragQueryFile hDrop, 0, varptr(file), 260 : DragFinish hDrop
alCreateImageByFile 0,file : if stat != 0 : return
screen 0,alGetWidth(),alGetHeight(),screen_hide : DragAcceptFiles hwnd, 1
;--------------------------
alGetBitmapPVData_start _size, _bitmap ; alpha付きbitmap取得(ロックしたまま)
lwAlpha _bitmap, 255 ; ←追加した命令
alGetBitmapPVData_end ; (ロック解除)
;--------------------------
gsel 0,2 : redraw 1
return
*WM_LBUTTONDOWN
gsel ginfo_intid
sendmsg hwnd , 0x00a1 , 0x02 , lparam
return
*ON_KEY
if iparam = 27 : end
return
ただ、 alGetBitmapVData命令内の GdipBitmapLockBits をすぐアンロックしてしまうと上手くいかないようなので(?)、ロックしたままにして使ったあとアンロックしています。
(なんで PixelFormat32bppARGB の場合は問題ないのに、PixelFormat32bppPARGB だと上手くいかないのかはよくわかっていません;;)
| |
|
2022/7/16(Sat) 10:44:20|NO.96813
>MIZUSHIKIさん
素晴らしいですね! Artlet2Dを改造しないと出来ないなぁと思ってたのですが、
拡張の記入の発想。大変参考になりました。
ロックビットは私的には使い終わったらアンロックするようなイメージがあったので、
元がすぐにアンロックして動いているのが不思議に思ってました。
MIZUSHIKIさんのやり方が正しいと考えてます。
|
|
2022/7/16(Sat) 12:09:34|NO.96814
ご指摘を反映して修正と整理をしてみました。
Artlet2Dのカレントイメージで現在のスクリーンをレイヤーウインドウで表示します。
速度的な問題はなさそうです。
;================================================
; Include guard
#ifndef alInitModule
#include "a2d.hsp"
#endif
#ifndef lwAlpha
#module LAYERED_WINDOW
; gdi+ ----------------------
#const PixelFormat32bppPARGB $E200B
; gdi32 ---------------------
#uselib "gdi32.dll"
#func CreateDIBSection "CreateDIBSection" sptr,sptr,sptr,sptr,sptr,sptr
#cfunc CreateCompatibleDC "CreateCompatibleDC" sptr
#func DeleteDC "DeleteDC" sptr
#cfunc CreateCompatibleBitmap "CreateCompatibleBitmap" sptr,sptr,sptr
#func SelectObject "SelectObject" sptr,sptr
#func DeleteObject "DeleteObject" sptr
#func StretchDIBits "StretchDIBits" sptr,sptr,sptr,sptr,sptr,sptr,sptr,sptr,sptr,sptr,sptr,sptr,sptr
#define SRCCOPY 0x00CC0020
#define CAPTUREBLT 0x40000000
; user32 --------------------
#uselib "user32.dll"
#cfunc GetWindowLongA "GetWindowLongA" sptr,sptr
#func SetWindowLongA "SetWindowLongA" sptr,sptr,sptr
#func UpdateLayeredWindow "UpdateLayeredWindow" sptr,sptr,sptr,sptr,sptr,sptr,sptr,sptr,sptr
#cfunc GetDC "GetDC" sptr
#func ReleaseDC "ReleaseDC" sptr,sptr
#define GWL_STYLE -16
#define GWL_EXSTYLE -20
#define WS_EX_LAYERED 0x00080000
#define ULW_COLORKEY 0x00000001
#define ULW_ALPHA 0x00000002
#define ctype BLEND_FUNCTION(%1=255) (0x01000000|((%1&0xFF)<<16))
; Function ------------------
#deffunc lwAlpha int alpha
; a2dのカレントからLockBits
if imgValid@a2d == 0 { return -1 }
rect@a2d = 0, 0, imgWidth@a2d, imgHeight@a2d
dim BitmapData@a2d, 8
GdipBitmapLockBits@a2d imgImage@a2d, varptr(rect@a2d), 1, PixelFormat32bppPARGB, varptr(BitmapData@a2d)
dupptr bmp, BitmapData@a2d(4), BitmapData@a2d(0) * BitmapData@a2d(1) * 4
; スクリーンと互換性のあるデバイスコンテキスト、ビットマップ作成
hdcDst = GetDC(0)
hsrcdc = CreateCompatibleDC(hdcDst)
hbitmap = CreateCompatibleBitmap(hdcDst, ginfo_sx, ginfo_sy)
; ビットマップコピー
SelectObject hsrcdc, hbitmap
bmpinfo = 40, ginfo_sx, ginfo_sy, 1|(32<<16), 0 ,0,0,0,0,0
StretchDIBits hsrcdc, 0,0,ginfo_sx,ginfo_sy, 0,ginfo_sy,ginfo_sx,-ginfo_sy, varptr(bmp), varptr(bmpinfo), 0, SRCCOPY|CAPTUREBLT
; レイヤードウインドウ
SetWindowLongA hwnd, GWL_EXSTYLE, GetWindowLongA(hwnd, GWL_EXSTYLE) | WS_EX_LAYERED
ptDst = ginfo_wx1, ginfo_wy1 : size = ginfo_sx, ginfo_sy
ptSrc = 0, 0 : blend = BLEND_FUNCTION(alpha)
crKey = 0 : dwFlags = ULW_ALPHA
UpdateLayeredWindow hwnd, hdcDst, varptr(ptDst), varptr(size), hsrcdc, varptr(ptSrc), crKey, varptr(blend), dwFlags
; 解放
ReleaseDC 0, hdcDst : DeleteObject hbitmap : DeleteDC hsrcdc
GdipBitmapUnlockBits@a2d imgImage@a2d, varptr(BitmapData@a2d)
return
#global
#endif
;================================================
; サンプル
#uselib "shell32.dll"
#func DragAcceptFiles "DragAcceptFiles" sptr,sptr
#func DragQueryFile "DragQueryFileA" sptr,sptr,sptr,sptr
#func DragFinish "DragFinish" sptr
alpha = 255
DragAcceptFiles hwnd, 1
oncmd gosub *WM_DROPFILES, 0x0233
oncmd gosub *WM_LBUTTONDOWN, 0x0201
onkey gosub *ON_KEY
stop
*WM_DROPFILES
hDrop = wParam : sdim file, 260 : DragQueryFile hDrop, 0, varptr(file), 260 : DragFinish hDrop
alCreateImageByFile 0,file : if stat != 0 : return
screen 0,alGetWidth(),alGetHeight(),screen_hide : DragAcceptFiles hwnd, 1
lwAlpha alpha : gsel 0,2
return
*WM_LBUTTONDOWN
sendmsg hwnd , 0x00a1 , 0x02 , lparam
return
*ON_KEY
if wparam = 27 : end
if wparam = 38 : alpha = limit(alpha+16, 32,255)
if wparam = 40 : alpha = limit(alpha-16, 32,255)
alSelectImage 0 : lwAlpha alpha
return
| |
|
2022/7/16(Sat) 14:15:37|NO.96816
usagi様、MIZUSHIKI様、ありがとうございます。
素晴らしく完璧です!自分も早く同じような事が出来るようになりたいです。
後は頑張って組み込んでみます。
仕組みの完全な理解は時間が掛かりそうですが^^;
|
|