TWSNMP FC:マップの背景画像を表示できた
今朝は4時い猫に起こされました。でも猫のお世話した後、二度寝して5時に起きると猫はいませんでした。かみさんの布団に潜っていたようです。イアフォンをつけてプログラムを作っていたら、いつの間にか猫は私の後ろのベッドで寝ていました。かみさんによると戸を開けろと大騒ぎして、かみさんを起こしてしまったらしいです。すみません。
さて今朝はマップの背景の画像を表示する続きです。画像ファイルの保存不法について寝ている間によいアイデアが浮かびました。画像をファイルではなくデータベース(bbolt)に保存する方法です。さっそく試してみました。
bboltは、バイト列にキーをつけて保存するものなので、わりと簡単にできました。うれしい。注意するのは、アップロードしたファイルのサイズをチェックすることです。大きすぎるとデータベースに問題がおきると思います。
保存は、
func (ds *DataStore) SaveBackImage(img []byte) error {
return ds.db.Update(func(tx *bbolt.Tx) error {
b := tx.Bucket([]byte("config"))
if b == nil {
return fmt.Errorf("bucket config is nil")
}
return b.Put([]byte("backImage"), img)
})
}
読み出しは
func (ds *DataStore) GetBackImage() ([]byte, error) {
var r []byte
if ds.db == nil {
return r, ErrDBNotOpen
}
return r, ds.db.View(func(tx *bbolt.Tx) error {
b := tx.Bucket([]byte("config"))
r = b.Get([]byte("backImage"))
return nil
})
}
です。読みだした画像データをWebサーバーの応答として返すのは
func getBackImage(c echo.Context) error {
api := c.Get("api").(*WebAPI)
img, err := api.DataStore.GetBackImage()
if err != nil {
log.Printf("postBackImage err=%v", err)
return echo.ErrNotFound
}
ct := http.DetectContentType(img)
return c.Blob(http.StatusOK, ct, img)
}
のようにしました。ここで2つ技を習得しました。
バイト列のバイナリーデータのContent-Typeを調べる技は、
を参考にしました。バイナリーデータを応答するのは、
のBlobを参考にしました。
サーバー側はできたのでブラウザー側で表示する処理を作りました。P5.jsでイメージを読み込むのは、
を参考にして、
const setMAP = (m,url) => {
nodes = m.Nodes
lines = m.Lines
backImage = m.MapConf.BackImage
backImage.Image = null
const _p5 = new P5()
_p5.loadImage(url+'/backimage',(img)=>{
backImage.Image = img
mapRedraw = true
})
mapRedraw = true
}
のように行いました。読み込んだ画像は表示の処理で
p5.draw = () => {
if (!mapRedraw){
return
}
mapRedraw = false
p5.background(23)
if(backImage.Image){
if(backImage.Width){
p5.image(backImage.Image,backImage.X,backImage.Y,backImage.Width,backImage.Height);
}else {
p5.image(backImage.Image,backImage.X,backImage.Y);
}
}
のようにしました。
いろいろやった結果
のように表示できました。今日はいろいろ小技を習得できたました。うれしい。今朝の作業は、
です。明日に続く。
開発のための諸経費(機材、Appleの開発者、サーバー運用)に利用します。 ソフトウェアのマニュアルをnoteの記事で提供しています。 サポートによりnoteの運営にも貢献できるのでよろしくお願います。