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


HSPTV!掲示板


未解決 解決 停止 削除要請

2021
0701
きり梅画像の乗算処理について5解決


きり梅

リンク

2021/7/1(Thu) 10:43:52|NO.93134

二つの画像を乗算処理させたくてhspcvのcvcopy命令を使ったのですが、
求めていた処理が「RGB値*RGB値/255」なのに対してcvcopyの乗算処理は「RGB値*RGB値」になっているようです。
「RGB値*RGB値/255」の乗算処理ができる有志によるモジュールも見つけたのですが、処理が遅くて求めてるものには使いづらいです。
なるべく高速で「RGB値*RGB値/255」の乗算処理ができる方法はないでしょうか。

見つけたモジュール
https://mclab.uunyan.com/dl/dl38.htm



この記事に返信する


沢渡

リンク

2021/7/2(Fri) 13:59:32|NO.93143

仮のバッファを作って合成したい座標を横に並べ、
コピー先を黒く塗りつぶした上でgmode 7でgcopyすれば
お望み通りの結果になるのではないでしょうか。
(gmode 7でのコピーは遅いので、満足いく速度かどうかはわかりませんが…)

その作業をモジュール化してみました。
以下は、提示されたサイトのサンプルを借用して実行した例です。

//使い方: //・あらかじめ //mul_copy_init p1,p2,p3 //を実行しておく。p1は作業用の画面ID、p2は横幅、p3は縦幅 // //・その後、 //mul_copy p1,p2,p3 //を実行すれば、カレントポジションに対して乗算コピーが行われる。 //p1はコピー元の画面ID、p2はコピー元のX座標、p3はコピー元のY座標 //(実行後はgmode 0になり、カレントカラーは0,0,0になるので注意) #module #deffunc mul_copy_init int _tmp,int _w,int _h id0=ginfo_sel tmp=_tmp : w=_w : h=_h buffer tmp,w*2,h : gsel id0 return #deffunc mul_copy int id,int x,int y id0=ginfo_sel : x0=ginfo_cx : y0=ginfo_cy gsel tmp : gmode 0 pos 0,0 : gcopy id0,x0,y0,w,h pos w,0 : gcopy id,x,y,w,h gsel id0 : gmode 0 : color 0,0,0 : boxf x0,y0,x0+w-1,y0+h-1 gmode 7 : pos x0,y0 : gcopy tmp,0,0,w,h gmode 0 : return #global //以下実行例。 //(https://mclab.uunyan.com/dl/dl38.htm のものを借用しました) ;基本画像 screen 0 : title "基本画像" gradf 0, 0, 30, 30, 0, $000000, $ffffff color 0,0,0 ;合成画像 screen 1 : title "合成画像" color 0,0,0 : boxf 0,0,29,29 gradf 0, 0, 30, 29, 1, $ffffff, $000000 color 0,0,0 gsel 0, 1 pos 100, 100 gcopy 0, 0,0, 30,30 ;コピーした基本画像に合成画像を合成 pos 100, 100 mul_copy_init 100,30,30 mul_copy 1, 0,0 pos 100, 135 mes "合成結果"



沢渡

リンク

2021/7/2(Fri) 15:59:48|NO.93144

×「合成したい座標を横に並べ」
○「合成したい画像2つを横に並べ」
です。失礼いたしました。



雪月夜

リンク

2021/7/4(Sun) 13:51:48|NO.93155

沢渡さんのコードですと、vram_gcopyモジュールの出力結果とは微妙に色の違いがあるようですね
モジュールの機能を完全に再現してかつ高速な処理となると
他には無さそうなので自作するしかないかもしれません

一応こちらでも乗算処理だけを行うコードを組んでみました
マシン語を使っているので速度は申し分ないと思います

#uselib "kernel32.dll" #func global VirtualProtect "VirtualProtect" var,int,int,var #define global xdim(%1,%2) dim %1,%2:VirtualProtect@ %1, %2*4,$40,AZSD #module //ImageSynthetic_Mul p1,p2,p3 //p1は合成結果を出力する画面ID、p2は基本画像のバッファID、p3は合成画像のバッファID #deffunc ImageSynthetic_Mul int displayid,int basicid,int syntheticid xdim code, 117 code.0 = $53565755, $8b2cec83, $8b48246c, $8b5c245c, $8d4c2444, $03a84004, $00d9840f, $c1990000 code.8 = $d0011eea, $2903e083, $01728dc2, $012404c7, $8d000000, $03a85b04, $00ca840f, $c1990000 code.16 = $d0011eea, $2903e083, $01528dc2, $000001b8, $03e98900, $3960244c, $6d8d0fcd, $01000001 code.24 = $850c8dd8, $00000000, $cf29c789, $d129f989, $20244c89, $60247c8b, $0fff4f8d, $048dc1af code.32 = $d1af0f40, $c789d001, $54247c03, $14247c89, $58244403, $18244489, $0324048b, $8d4c2444 code.40 = $00008514, $c7890000, $fa89d729, $5489f229, $4c8b2424, $e9295024, $0f01e983, $f289f1af code.48 = $89c1af0f, $244c03c1, $490c8d44, $4c03f101, $4c894024, $5c031c24, $5c894424, $d8012824 code.56 = $0340048d, $01402454, $244489d0, $2444c70c, $00000010, $be4beb00, $00000000, $002404c7 code.64 = $e9000000, $ffffff2b, $000000ba, $0000b800, $3ae90000, $83ffffff, $01102444, $1024448b code.72 = $20247c8b, $14247c01, $18247c01, $24247c8b, $1c247c01, $0c247c01, $60244439, $008a840f code.80 = $448b0000, $44392824, $cb7d4424, $1c247c8b, $18246c8b, $1424448b, $b60fc689, $b60f014e code.88 = $04890145, $46b60f24, $24448902, $55b60f04, $24548902, $1eb60f08, $0055b60f, $b8daaf0f code.96 = $80808081, $da01ebf7, $8807fac1, $0caf0f17, $8081b824, $e9f78080, $f9c1d101, $014f8807 code.104 = $04244c8b, $244caf0f, $8081b808, $e9f78080, $fac1ca01, $02578807, $8303c683, $c78303c5 code.112 = $247c3b03, $e993750c, $ffffff4b, $5b2cc483, $c35d5f5e ;基本画像バッファ gsel basicid mref vram_b,66 bgw=ginfo(12):bgh=ginfo(13) ;合成画像バッファ gsel syntheticid mref vram_s,66 ;出力結果ウィンドウ gsel displayid mref vram_d,66 gw=ginfo(12):gh=ginfo(13) x=ginfo(22):y=ginfo(23) ;実行後は出力結果ウィンドウがアクティブになる prm=varptr(vram_d),x,y,gw,gh,varptr(vram_b),varptr(vram_s),bgw,bgh pcode=varptr(code) return callfunc(prm, pcode, 9) #global imagew=300 ;基本画像 buffer 1,imagew,imagew gradf 0, 0, ginfo(12), ginfo(13), 1, $ffffff, $000000 ;合成画像 buffer 2,imagew,imagew gradf 0, 0, ginfo(12), ginfo(13), 0, $000000, $ffffff gsel 0 ;出力座標指定 pos 100,50 ;画像合成 ImageSynthetic_Mul 0,1,2 redraw



沢渡

リンク

2021/7/4(Sun) 18:40:01|NO.93157

そんなバカな、と思ってOpenHSPを確かめてみたところ、
vram_gcopyモジュールだと255で割っているが、gmode 7の場合は256で割っているようですね。
(以下のコードの1678行目のあたり。>>8は256で割るのと同じこと)
https://github.com/onitama/OpenHSP/blob/eddc647733e82657757055b66fd8c2dbf17898b8/src/hsp3/win32gui/hspwnd_win.cpp
良いアイディアだと思いましたが、これは失礼いたしました。
さすがにマシン語のコードを組めるような方には脱帽です。



きり梅

リンク

2021/7/4(Sun) 19:55:28|NO.93158

沢渡さん、雪月夜さん、返信ありがとうございます。
書いてたプログラムの別のバグの対応にてこずり、返信が遅れてしまいました。すみません。

お二人から頂いたコードを試してみたのですが、使いたい画像でも十分すぎるほど素早く合成してくれました。
雪月夜さんのほうはまさかマシン語で書いていただけるとは思いませんでした。大変ありがたいです。

gmode 7とvram_gcopyではわずかに処理が違うのですね。勉強になります。

お二人のおかげで作りたかったものが完成しそうです。大変助かりました!



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