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


HSPTV!掲示板


未解決 解決 停止 削除要請

2012
0723
かとりせんこうHSPでHDDに保存せずに画像ファイルを利用したい!!17解決


かとりせんこう

リンク

2012/7/23(Mon) 15:13:53|NO.47840

HSPでネットから画像をダウンロードし、表示するスクリプトを書きました。


#include "hspinet.as" netinit neturl "http://upload.wikimedia.org/wikipedia/commons/6/6b/" netload "Phalaenopsis_JPEG.jpg" picload "Phalaenopsis_JPEG.jpg"

(例なので、エラー処理等は全くしていません。)

この場合、netloadで、いったん、HDDに画像ファイルをダウンロードし、picloadで表示している形になります。
そうすればHDDにアクセスすることになり、大量の画像をネット経由で利用する場合、HDDに負担は掛かりますし、時間も掛かります。
それで質問なのですが、直接メモリに画像ファイルをダウンロードする事は出来ないでしょうか?
つまりはHDDをバイパスせずに直接メモリに画像ファイルをダウンロードしてきて、利用する事は出来ないのでしょうか?
何らかのやり方があれば、教えてください。
お願いします。



この記事に返信する


@key

リンク

2012/7/23(Mon) 15:36:41|NO.47841

http://www.binzume.net/software/forhsp.html
の「ダウンロード用モジュール for HSP」にそのような機能があるみたいです



かとりせんこう

リンク

2012/7/23(Mon) 23:09:43|NO.47862

@key様、回答ありがとうございます。
びんずめ堂様の”ダウンロード用モジュール for HSP”を観させていただきました。

ただ、僕の力不足・勉強不足で、イマイチ、その意味がよく判っておらず、テストソースも書けない状況です、苦笑。
後HSP3.3で今回、作成しているために、2.6仕様のモジュールが使えるか?って不安もあります。
’テストソースも書けていないのに、不安を感じる自分自身にも問題があるとは判っているのですが・・・)

ダウンロード用モジュール for HSPの場合は、hspsock.dllをモジュールで呼び出して使用する!!って事のようですが、今回、hspinet.asのインクルードでソースを書き始めているために、netloadの保存位置をメモリ空間に持っていきたい!!ってのが希望になるのです。
逆に言えば、メモリを何らかの形で仮想フォルダーとして切り取る事が出来れば、後は保存フォルダーの指定でOKなんだと思うんです。
そう言ったことが出来るasファイルがあればうれしいのですが・・・・笑

こちらも研究させていただきたく思いますが、引き続き、メモリ空間に簡単にファイル操作が出来る機能がありましたら、お教え願いたく思います。
よろしくお願いします。



inovia

リンク

2012/7/23(Mon) 23:20:39|NO.47864

HSP3.31β1以降であれば、netgetv命令でダウンロードしたバイナリデータを直接変数に格納することができます。
それとmemfile命令を組み合わせることで実現可能かと思います。


// HSP3.31β1以降が必要です // http://www.onionsoft.net/wp/archives/730 // sample\hspinet\test6.hsp #include "hspinet.as" ; ; ファイルの取得(メモリ上に取得) ; netinit neturl "http://upload.wikimedia.org/wikipedia/commons/6/6b/" netrequest_get "Phalaenopsis_JPEG.jpg" mes "DOWNLOAD 開始" *main ; 結果待ちのためのループ netexec res if res > 0 : goto *comp if res < 0 : goto *bad await 50 goto *main *bad ; エラー neterror estr mes "ERROR "+estr stop *comp ; 完了 mes "DOWNLOAD 完了" // 変数にダウンロードしたデータを保存 netgetv buf // メモリストリーム設定 memfile buf, 0, stat // picloadで読み込み picload "MEM:a.jpg" stop



かとりせんこう

リンク

2012/7/24(Tue) 18:29:59|NO.47893

inovia様、回答、ありがとうございます。

実行したところ、最後のpicloadのところでエラーになってしまいます。

”netrequest_get”でメモリに書き込んで、”netgetv”でbufを変数にしてアクセスできるようにしているって感じだと思います。
ただ、netgetvの説明には、自動的に必要なサイズを確保した文字列型として初期化されます。”と書かれています。
そうなれば、バイナリデータであるjpgであるのに、str型で読み込むことになると思うんですね・・・
そうなるとデータのキャストが必要になってくると思うんですね・・・
そして、キャストの仕方、調べたのですが、よく判っていません、苦笑

後、メモリストリーム機能がよく判っていません。
簡単に言えば、変数をメモリに宣言して、HDDの実データをメモリに書き込んで利用するって感じなのでしょうか?
”note〜”命令群のようにテキストデータではなく、WAVなどのデータを少しずつ読み込むときに使うっぽく感じています。
そうなれば、netgetvで定義しているんですから、memfileで再度宣言する意味がよく判らなくなっていくんですね。
単純に複数のメモリ上にある変数を呼び出すのに、おまじないのごとく、宣言するための命令だと考えていいのでしょうか?
そのあたりも曖昧で、良く判っていません。

せっかく教えていただいたのに、理解も出来ずに質問ばかりで、申し訳ありません。
お許しいただきたく思います。
よろしくお願いします。



神事

リンク

2012/7/24(Tue) 19:54:21|NO.47898

>>inovia
実行では問題なく動くのですが
EXE化して実行させるとpicloadの部分でシステムエラーが出るようです。



かとりせんこう

リンク

2012/7/24(Tue) 20:48:20|NO.47899

神事様
追試験、ありがとうございます。
こちらは、エディタでのF5実行でエラーになります。

OSはWindows7でC:\hsp33がインストール先になります。
HSPのバージョンは3.3で、外部DLL等はまったくインストールしておりません。
保存先はマイドキュメントにしています。

なぜこのような”差”が出るのでしょうか?
教えてください。
よろしくお願いします!!



暇人

リンク

2012/7/24(Tue) 21:42:38|NO.47902

>OSはWindows7でC:\hsp33がインストール先になります。
フォルダがhsp33なら
それは3.3じゃないの?

http://www.onionsoft.net/wp/archives/722
もし3.3ならこれを落としてインスト
xp環境だけどNO.47864のは問題なく実行できる(exeにしても)



かとりせんこう

リンク

2012/7/25(Wed) 13:27:50|NO.47923

暇人様、回答ありがとうございます。

HSPのヴァージョンをおしえていただいたものにして動作しました。
せっかく、inovia様が”HSP3.31β1以降”と書いてくださっていたのに、それを完全に読み損ねていました。
皆様に、大変ご迷惑おかけしました。
お詫びと共に重ねて御礼申し上げます。

ただ、神事様が書かれているように、”EXE化して実行させるとエラーが出ます。
”#Error 1-->内部エラーが発生しました(1)”のダイアログが出てきます。

なぜでしょうか?

今回、考えているアプリケーションは、Yahooボックスなんかにある画像ファイルの表示プログラムで、
CSV形式で、そのURLを保存しておき、noteselで、その作成したCSVデータを読み込み、単純にボタンを押せば、次々とCSVデータの並びどおりに、
表示させていく!!ってだけのものを考えています。

実際、memfileによるメモリストリーム機能が良く判らなかったのですが、
inovia様のソースを利用して、自分自身のソースを書き直したところ、上手く動作しました。

ただ、思う事は、複数のデータをメモリに書き込むって事になるのですが、
buf変数としてとったメモリ空間にどんどん、新しい画像データを書き込んでいく事になってるんですけれども、
そのガーベージは考えなくていいのでしょうか?
データは、”netrequest_get”命令で上書きされて、古いデータは残らない!!って考えれば良いのでしょうか?

また、netrequest_get命令を利用する前に、何らかの命令でメモリ空間に大きさ可変の空間を変数として確保しておき、
netrequest_get命令ごとに、変数の中身を書き換えるイメージであるなら、判りやすいのですが、
今回の場合、メモリに取得してから変数bufで管理しているように思えます。
そうなった場合、複数のデータを同時にメモリにあげる事が出来ない!!って考えるべきなのでしょうか?

重箱の隅をつつくような質問ばかりなんですが、根本的にメモリストリーム機能の概念が判っていません。
その辺り、もしよろしければ、ご回答願います。
よろしくお願いします。



かとりせんこう

リンク

2012/7/25(Wed) 13:31:24|NO.47925

すいません、追伸です。
自分自身のソースで、上手くいったのは、エディタでのF5実行の場合です。
きちんと書けなくて申し訳ないです。
重ねて報告します。



神事

リンク

2012/7/25(Wed) 13:54:49|NO.47926

横から入ってすいませんが
hspinet.dllが同ディレクトリにないからではないでしょうか?
自分はそのexeとhspinet.dllを同じ場所に置いたらちゃんと動作しました!



MillkeyWeler

リンク

2012/7/25(Wed) 14:17:04|NO.47927

上記、inovia 様が提示されているソースの通り、メモリストリーム機能については、「ある特定のメモリ領域を参照しろ」
という命令であります。

inovia さんのソースの説明だと、picload する直前の netgetv buf にて、変数指定と、HSP の自動変数拡張機能で、自動的に変数のサイズが
取得したファイルのサイズとなっております。

また、事前に自身でメモリサイズを指定する事も可能です。
事前に自身でメモリを確保する時には、必ず、memfile 命令の第二引数及び第三引数を正しく指定してください。

[応用版の説明]
変数 A を仮に、1230000 byte 確保する。(memfile 専用変数)
変数 buf を使い、ネットからダウンロード(メモリロード)する。

そうすると、buf には、36323 byte のファイルがロードできる。
それを、変数 A の オフセット 0 から 36322 へコピーを行う。

次の画像も一緒にダウンロード(仮 13152 byte) とするしたいから、変数 buf に新しいファイルをダウンロードする。
でも、変数 A は、0〜36322 が使われているから、36323 からじゃないと使えない。

変数 A の最大サイズが、まだ余裕があるので、36323 からへ新しいファイルを書き込もう。

んで、最初の画像を表示し終えたら、memfile の第二引数と第三引数を 36323,13152 にすれば、2枚目の画像を指定したことになる。
最終的に、変数 A の最大のサイズを超える場合には、変数 A に書き込む場所(オフセット)を最初に戻してあげればいい。

これが、memfile メモリストリームの機能。

;-
>>ただ、思う事は、複数のデータをメモリに書き込むって事になるのですが、
>>buf変数としてとったメモリ空間にどんどん、新しい画像データを書き込んでいく事になってるんですけれども、
>>そのガーベージは考えなくていいのでしょうか?
>>データは、”netrequest_get”命令で上書きされて、古いデータは残らない!!って考えれば良いのでしょうか?

なのですが、同じ場所へ書き込むので、データは確実に上書きされます。
(ただし、元々サイズが大きい物から小さい物を扱う場合、消去できない可能性もあります。)



かとりせんこう

リンク

2012/7/25(Wed) 16:44:27|NO.47930

神事様、再度の回答、ありがとうございます。
hspinet.dllの件ですが、古い(Ver3.3)のものを使っていました。
新しいものに置き換えると完全動作しました。
申し訳ありません。
バージョン違いを無視していました。反省します。

MillkeyWeler様、回答ありがとうございます。
MillkeyWeler様の回答を読ませていただくと、
memfileでのメモリストリーム機能は、
大きなデータのファイルをシーケンシャル的に使うって感じになるんですね・・・
つまりはnetrequest_get命令でメモリに読み込ませた場合は、頭から書き込まれて、
その為に使用する時は、memfile命令の第二引数と第三引数で指定してやる必要がある!!って事なんですね・・・
それで上書きできなかったデータのメモリに残った部分(大きなデータを格納していて、小さなデータを上書きした場合)は
ゴミになって、絶えず、残滓として存在して、アプリケーション終了時なんかに、
OSのガーベージ機能で、初めて全てを綺麗に消えてしまう!!って感じなのでしょうか?
つまりはメモリにロードするごとに、メモリ空間を空にする命令を挟む事が出来ない!!ってことになると考えていいんでしょうか?

そう考えれば、複数のデータをロードする時、各データに対応する変数を宣言しておいて、変数ごとにメモリ空間にアクセスする!!って感じではなく、
シーケンシャルにひとつながりのデータとしてメモリに、大きさ指定でアクセスするって形になるって理解するべきなんでしょうね・・・

複数のデータを扱う時は、いったんハードディスク上に実ファイルとして書き込み、
その後、bsave命令等で、その複数ファイルを順番にマージして1つのファイルにし、
それを、noteload命令なんかで書き込んで、
その後、memfile命令の第二引数及び第三引数を指定する事で、
利用するって形になるようですね・・・

今回、実はNO.47923で書かせていただいたとおり、
netrequest_get命令の前にnotesel等でメモリに
CSVファイルをアップしている作りにしちゃいました。
そうなれば、netrequest_getで取得したファイルとアクセスするソース上の変数宣言が異なっていても、
結局はひとつながりになるのではないか?と思ってしまったのです。
特にnetrequest_get命令の前にメモリの変数宣言を行っていたいために、
そのあたりの管理が難しく感じてしまったのです。

HSPはnotesel命令で利用するstr型のデータとnetrequest_get命令なんかで取得するバイナリ系のデータとの2つで、
メモリ空間を管理していると考えていいのでしょうか?
重箱の隅をつついたややこしい質問になりましたが、教えていただければうれしく思います。
よろしくお願いします。



MillkeyWeler

リンク

2012/7/25(Wed) 19:28:22|NO.47933

一応、応用版を作ってみたのでスクリプトを書いておくね。

#include "hspinet.as" sdim MemoryBuffer,10240000 //メインメモリバッファ(一度にダウンロードする容量を考えて) dim MemoryInfo,2,1024 //メインメモリバッファ管理情報[Offset / Filesize] MemoryOffset = 0 //オフセット用 netinit neturl "http://upload.wikimedia.org/wikipedia/commons/6/6b/" mes "DOWNLOAD 開始" repeat 10 filename="Phalaenopsis_JPEG.jpg" // 複数のファイルを扱うなら、ここを変更してね。 netrequest_get filename repeat netexec res if res > 0 : gosub *comp : break if res < 0 : gosub *bad : break await 50 loop mes "MemoryOffset : "+MemoryInfo(0,cnt)+" / Filesize : "+MemoryInfo(1,cnt) loop //MemoryInfo 2番の情報を使い画像を表示してみる。 memfile MemoryBuffer,MemoryInfo(0,2),MemoryInfo(1,2) pos 0,0 : picload "MEM:a.bmp",1 stop *bad neterror estr mes "ERROR "+estr return *comp mes ""+filename+" のダウンロードが完了" netgetv buf //←ファイルのサイズが stat に代入されているので、それを別の変数にコピー filesize=stat //←ファイルサイズ stat を filesize にコピー memcpy MemoryBuffer,buf,filesize,MemoryOffset,0 MemoryInfo(0,IndexCNT)=MemoryOffset,filesize : IndexCNT++ MemoryOffset + filesize return

このスクリプトは、基礎的なことしかしてないので、後々メモリにあるファイルを消したい
などの時は、それ専用のスクリプトなどが必要になるよ。

csv なども、ダウンロード方式にしちゃえば、HDDにアクセスする必要もほぼなくなるかと。



暇人

リンク

2012/7/25(Wed) 20:20:44|NO.47937

何故かnetgetv後のstatは256kバイト固定なので
netfileinfoでファイルサイズ取得して一つのバッファに追加してく方法

#include "hspinet.as" netinit neturl "http://hsp.tv/images/bbs/" screen 1,640,480,2 gsel 0 fname={" mascot1.jpg mascot2.jpg mascot3.jpg mascot4.jpg mascot5.jpg mascot6.jpg mascot7.jpg mascot8.jpg mascot9.jpg "} sdim membuf msize=0 mes "DOWNLOAD 開始" CL="Content-Length: " CLlen=strlen(CL) notesel fname repeat notemax noteget f,cnt button gosub f,*draw netfileinfo finfo,f if stat or (instr(finfo,0,"image/jpeg")=-1) :mes finfo:stop index = instr(finfo,0,CL)+CLlen fsize(cnt)=int( strmid(finfo,index,instr(finfo,index,"\n"))) mes f+" サイズ:"+fsize(cnt) netrequest_get f repeat netexec res if res > 0 : break if res < 0 : goto *bad await 50 loop netgetv buf memoffset(cnt)=msize memexpand membuf,memoffset(cnt)+fsize(cnt)//必要な分を再確保 memcpy membuf,buf,fsize(cnt),msize,0 msize+fsize(cnt) wait 1 loop mes "DOWNLOAD 終了" stop *draw id=stat gsel 1 memfile membuf, memoffset(id), fsize(id) picload "MEM:a.jpg" return *bad ; エラー neterror estr mes "ERROR "+estr stop



かとりせんこう

リンク

2012/7/27(Fri) 13:53:53|NO.47968

MillkeyWeler様、暇人様、回答ありがとうございます。
お二人共に、判り易くスクリプトまで書いていただきまして、すっごく理解しやすかったです。
複数のファイルを扱うときは、ファイルごとの大きさをアドレスっぽく使って、足して1つにしたものを切り出して使うって感じですね・・・
勉強になりました。
メモリの掃除に関しては、アプリケーション終了時に、OSのガーベージに任せるとして、
今回は、僕なりに理解できたとして、解決としたいと思います。
教えていただいたとおりのテクニックを使って、これからどんどん、HSPを勉強したいと思います。
今回は本当にありがとうございました。
また、機会がありましたら、その時もよろしくお願いします!!
今回は、お手数をおかけして申し訳ありませんでした。
お礼申し上げます。



暇人

リンク

2012/7/27(Fri) 20:27:33|NO.47981

>メモリの掃除に関しては、アプリケーション終了時に、OSのガーベージに任せるとして、
HSP側の変数は再初期化すれば最小(HSP仕様上の)のサイズになる
NO.47937ので言うと
>netgetv buf
のbufは必要無くなったらdim buf,1とでもすれば4バイトに減らせる(netgetvで使うときは勝手に文字列型になる)
全部の画像データを入れてるmembufも新しく最初からデータを入れる前に
sdim membufとすれば64バイトになる

netrequest_getで使われるメモリはDLL側の管理だからソフト終了で開放される



かとりせんこう

リンク

2012/7/27(Fri) 21:07:25|NO.47984

暇人様、丁寧な回答、ありがとうございます。
そうですね・・・変数をsdim命令なんかで再宣言してやれば、それで初期化されるんですね・・・
end命令の前なんかに、使用していた変数を再宣言して初期化してやってから、終わるほうが綺麗ですね。
美しいプログラムの書き方、勉強になります。
これからも頑張ってHSP、勉強していきたく思いますので、また、何かありましたら、ご協力、お願いいたします。
今回は、本当にありがとうございました。



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