HSPポータル
サイトマップ お問い合わせ


HSPTV!掲示板


未解決 解決 停止 削除要請

2018
0805
Kain透明な部分があるpng画像をボタンにしたいんですが...13解決


Kain

リンク

2018/8/5(Sun) 00:00:19|NO.84975

※HSP初心者です
※文が意味わからんことになってるかもです

角に丸みを帯びた四角形のボタン(不要な部分を透明にしています)をpngで保存して、
それをHSPで読み込んでobjimage命令でその透明な部分のあるpngファイルを指定したところ、
透明な部分が黒色で表示されます。objimage命令でも透明情報(?)を維持したまま画像ボタンを
作成(表示)するにはどうしたらよいですか?
ネットで探しても、大抵が拡張子がgifファイルだったりで...

そもそもobjimge命令では透明部分が含まれた画像を表示させるのは不可能なのでしょうか?



この記事に返信する


あらや

リンク

2018/8/5(Sun) 01:55:30|NO.84976

>objimage命令では透明部分が含まれた画像を表示させるのは不可能なのでしょうか?
HSPのバッファなどに読み込んだ時点で透明度(アルファ値)は消滅しています。

透過情報を扱うArtlet2Dもありますが、objimageと同時には使えないでしょうね。

試していないのでなんとも言えませんが
不定形リージョンをボタンの形状に適用すればできるのかもしれません。



科学太郎

リンク

2018/8/5(Sun) 06:42:05|NO.84977

> そもそもobjimge命令では透明部分が含まれた画像を表示させるのは不可能なのでしょうか?
ボタンにリージョンを適用する方法以外にも
ボタンのオーナー・ドローを行うことで
見た目上は「丸角ボタン」になります。

ただし、ボタンの隅をクリックするとボタンが押された状態になりますので、
ボタンにリージョンを適用する方法と組み合わせると良いでしょう。



Kain

リンク

2018/8/5(Sun) 12:23:12|NO.84978

ネットでリージョンについてしらべたら、ウィンドウのリージョンオブジェクトについては
分かりましたが、ボタンや画像などのリージョンオブジェクトについてはわかりませんでした...
(もしかしたらウィンドウのリージョンオブジェクトとやり方は同じなのかもしれませんが
そのばあいどのようなソースを入力したらよいのか、よくわかりません...)



科学太郎

リンク

2018/8/5(Sun) 13:56:48|NO.84979

> もしかしたらウィンドウのリージョンオブジェクトとやり方は同じなのかもしれませんが

button gosub "", *Push h=objinfo_hwnd(stat)

この「h」がボタンのウインドウ・ハンドルです。
これに対してリージョンを設定する事になります。

ボタンにリージョンを適用させたらば、画像は特に矩形のままでも良いでしょう。



Kain

リンク

2018/8/5(Sun) 14:27:20|NO.84980

試した結果うまくいきました!!
それと、ついでにもう一つ質問なんですが、画像の不要な部分を黒色で塗りつぶして、
その黒色の部分だけ透明化させるにはどうすればよいですか?



あらや

リンク

2018/8/5(Sun) 15:22:36|NO.84981

wikiのソースですが
https://wiki.hsp.moe/%E4%B8%8D%E5%AE%9A%E5%BD%A2%E3%83%AA%E3%83%BC%E3%82%B8%E3%83%A7%E3%83%B3.html

これを少し改造すればボタンでも色によって
透過するかしないかを判別できるのではないでしょうか。



Kain

リンク

2018/8/5(Sun) 16:32:02|NO.84982

リージョンなどを使用して丸みを帯びたボタンを表示させることは出来ました。
ただ、この場合別のウィンドウを使用してボタンを表示させていることになってるらしいんですが、
ウィンドウID1に他の写真等と一緒に今回表示させたボタンを表示させるにはどうすればよいですか?
例えばOSもどきのように、ウィンドウID1に背景やmesテキスト、そこに今回表示させた透明な部分のある
画像を適用させたカスタムボタンを表示させるようにするほうほうです。

※あとから何言ってるか自分でもわかってません。あと頼りすぎてすいません...



あらや

リンク

2018/8/5(Sun) 16:47:49|NO.84983

えーっと、仰る通り何が何やらわかりにくいのですが
ボタンやリストボックスなどHSPでオブジェクトと言われる物は
本質的には元々そのオブジェクトを配置するウィンドウ(親)の子ウィンドウです。

タイトルバーなどが無いbgscrのウィンドウを
screenで作ったウィンドウに張り付けているような物
と考えるとわかりやすいでしょうか。

なので、どのウィンドウIDにあるボタンでも
objinfo_hwndでボタンのウィンドウハンドルを取得できますし
ウィンドウハンドルがわかればリージョンが使えるはずですよ。



Kain

リンク

2018/8/5(Sun) 17:05:11|NO.84984

試してみましたが、当たり前ですがうまくいきません...
objinfo_hwndでボタンのウィンドウハンドルを取得する方法、そこからわかりません...
ウィンドウハンドルについてもよくわかってないのですが、具体的にどのようなソース(?)
だと正常にウィンドウID0にこの命令などを活かしてボタンを表示させることができるのでしょうか?

※やっぱり意味わからん事いってますよね...
※頼りっぱなしで本当にすみません...><



あらや

リンク

2018/8/5(Sun) 18:42:17|NO.84986

どう試したのか、一旦ソースを拝見したいところですが
とりあえず操作対象ウィンドウに関してよくわかっておられないのでしょうか?

screen等のウィンドウ作成系の命令を使った直後は、作成したウィンドウIDが操作対象になる。
gselで操作対象ウィンドウIDが変更できる。

とりあえずこの2点だけ覚えた上で下記のソースを見てください。

// この時点では操作対象はID0 screen 0, 640, 480, 0 // ウィンドウID0を再定義しただけなので操作対象は0のまま screen 1, 300, 100, 0 // 新規にID1のウィンドウを作成したため、操作対象が1に変更された。 // ウィンドウID 0 にボタンを配置 gsel 0 // ID 0のウィンドウにボタンを配置したいのでgselで 0を指定する pos 10, 10 objsize 200, 20 button gosub "ウィンドウID:0のボタン", *btn0 // ボタン等のオブジェクトを作成した直後には stat にオブジェクトIDが入っている btn_id0 = stat // ボタンのオブジェクトID btn_hwnd0 = objinfo_hwnd(btn_id0) // オブジェクトIDからウィンドウハンドル取得 // ウィンドウID 1 にボタンを配置 gsel 1 // 今度はID 1のウィンドウにボタンを配置したいのでgselで 1を指定する pos 20, 10 objsize 200, 20 button gosub "ウィンドウID:1のボタン", *btn1 // オブジェクトIDはウィンドウによってそれぞれ0から順に空いている番号が割り振られる btn_id1 = stat // ボタンのオブジェクトID btn_hwnd1 = objinfo_hwnd(btn_id1) // オブジェクトIDからウィンドウハンドル取得 stop *btn0 dialog "ID 0のボタンが押された" return *btn1 dialog "ID 1のボタンが押された" return



Kain

リンク

2018/8/5(Sun) 20:54:42|NO.84988

となると、あらやさんが返信してくださったなかのURLのソースの丸みを帯びたボタンを描画する命令などを
先程あらやさんが教えてくださったソースないのウィンドウID0の所に追加で入力すれば、
ウィンドウID 0に丸みを帯びたボタンが配置できるということですか?(間違っていたらすいません...)
screen命令で指定したらウィンドウIDが操作対象になったりすることは分かりました。



あらや

リンク

2018/8/5(Sun) 21:54:20|NO.84989

wikiの3つ目のソースを少し改造したものです。
(そのまま使うとボタンではなくウィンドウ自体の形を変えてしまうので)

画像は円を描画したもので代用しました。

// 不定形リージョンウィンドウ作成 // CreatePolyPolygonRgn使用 // 通常のpget & CreateRectRgnに比べてかなり高速 // ただし、Windows9x系統では正常に動かない可能性あり // *ぼやき* // 恐らく一番早いのはExtCreateRectRgn。。。 // けど、引数の内容が面倒なのでこれで妥協 // ちなみにテスト画像は600x690(でか) // 普通の画像ならかなり早くなるはず // 必要なものをインクルード #include "user32.as" #include "gdi32.as" #include "winmm.as" // これはリージョン作成に直接関係無し // ウィンドウ移動制御用の定数 #define global WM_NCLBUTTONDOWN $000000A1 #define global HTCAPTION 2 // リージョン作成用の定数 #define global WINDING 2 // モジュール記述 #module // CreateWindowRgn p1(targetWin), p2(baseWin), p3(tr), p4(tg), p5(tb) // targetWin : 不定形リージョンを適用するウィンドウのハンドル // baseWin : 不定形リージョンを作成する絵があるウィンドウID // tr, tg, tb: 透過色にするRGB値 #deffunc CreateWindowRgn int targetWin, int baseWin, int tr, int tg, int tb now_sel = ginfo_sel; // 現在の描画対象ウィンドウIDを記録 gsel baseWin mref vram, 66 // 画像データを取得 dim pt, 100000 // 点データ用配列 dim ct, 100000 // 多角形点数記憶用配列 wx = ginfo_winx : wy = ginfo_winy // 画像サイズ取得 // 透過色指定の為これらは破棄 ;pget 0, 0 // 透明色の取得(点(0,0)の色を透明色にする) ;tr = ginfo_r : tg = ginfo_g : tb = ginfo_b // 変数初期化 // 注:yはデータ構造上、下から x = 0 : y = wy : flg = 0 : count = 0 : pt_cnt = 0 : poly_cnt = 0 repeat wy repeat wx // 画像データの構造にそってRGB値を取得 b = peek(vram,count) count++ g = peek(vram,count) count++ r = peek(vram,count) count++ // 透明色と比較 // 内部は説明面倒なので省略。やってることはIIと変わらない。 if (wx == x + 1) | ((r == tr) && (g == tg) && (b == tb)) { if flg == 1 { pt(pt_cnt) = x, y-1, x, y pt_cnt += 4 ct(poly_cnt) = 4 poly_cnt++ : flg = 0 } } else { if flg == 0 { pt(pt_cnt) = x, y, x, y-1 pt_cnt += 4 flg = 1 } } x++ loop x = 0 y-- loop // 取得した情報からリージョン作成(詳細はMSDNやその他サイト参照) CreatePolyPolygonRgn varptr(pt), varptr(ct), poly_cnt, WINDING tmpRgn = stat gsel now_sel // 描画対象ウィンドウを戻す SetWindowRgn targetWin, tmpRgn, 1 // リージョン設定 DeleteObject tmpRgn // 後片付け return #global // ボタンに乗せる画像1 buffer 10, 192, 64, 0; color 0, 0, 0: boxf; color 0, 0, 255; circle 0, 0, 64, 64, 1; circle 64, 0, 128, 64, 1; circle 128, 0, 192, 64, 1; color 0, 0, 0; pos 24, 22: mes "素"; pos 88, 22: mes "押"; pos 152, 22:mes "重"; // ボタンに乗せる画像2 buffer 11, 192, 64, 0; color 0, 0, 0: boxf; color 0, 255, 0; circle 0, 0, 64, 64, 1; circle 64, 0, 128, 64, 1; circle 128, 0, 192, 64, 1; color 0, 0, 0; pos 24, 22: mes "素"; pos 88, 22: mes "押"; pos 152, 22:mes "重"; // 透過色情報用の画像 buffer 12, 64, 64, 0; color 0, 0, 0: boxf; color 255, 255, 255: circle 0, 0, 64, 64, 1; // ウィンドウ作成 screen 0, 300, 200, 0, 0, 0; title "ID:0"; screen 1, 300, 200, 0, 400, 0; title "ID:1"; // ウィンドウID 0 にボタンを配置 gsel 0 pos 10, 10 objsize 64, 64 objimage 10, 0,0, 64,0, 128,0; button gosub "", *btn0 // ボタン等のオブジェクトを作成した直後には stat にオブジェクトIDが入っている btn_id0 = stat // ボタンのオブジェクトID btn_hwnd0 = objinfo_hwnd(btn_id0) // オブジェクトIDからウィンドウハンドル取得 // リージョン化(ボタンのウィンドウハンドル、透過情報画像のウィンドウID、透過色RGB値を渡す) CreateWindowRgn btn_hwnd0, 12, 0, 0, 0; // ウィンドウID 1 にボタンを配置 gsel 1 pos 20, 10 objsize 64, 64 objimage 11, 0,0, 64,0, 128,0; button gosub "", *btn1 // オブジェクトIDはウィンドウによってそれぞれ0から順に空いている番号が割り振られる btn_id1 = stat // ボタンのオブジェクトID btn_hwnd1 = objinfo_hwnd(btn_id1) // オブジェクトIDからウィンドウハンドル取得 // リージョン化 CreateWindowRgn btn_hwnd1, 12, 0, 0, 0; *main gsel 0: gosub *refresh; gsel 1: gosub *refresh; await 17; goto *main; *refresh redraw 0; color 255, 255, 255: boxf; redraw 1; return; *btn0 dialog "ID 0のボタンが押された" return *btn1 dialog "ID 1のボタンが押された" return

一応リージョン化して円形になってるはずなんですが
ボタンの上にマウスが重なったり、ボタンをクリックしたりすると
ときどき四角い形状に戻るという微妙なサンプルになってしまいました。



Kain

リンク

2018/8/6(Mon) 10:59:26|NO.84993

一瞬黒色の何かが表示されますが、ボタンの黒い部分はだいぶ透明になりました!
(少し黒色の部分が残ってしまいましたがw)

皆さんありがとうございました!
また機会がありましたら宜しくお願いします!



ONION software Copyright 1997-2021(c) All rights reserved.