Wio Terminal
発掘したのでさわってみる。
https://wiki.seeedstudio.com/Wio-Terminal-Getting-Started/ でgetting start
https://qiita.com/jksoft/items/c544d73b54323064ed06#プログラム書き込み のチカチカまではとりあえずできた。
https://wiki.seeedstudio.com/Wio-Terminal-Getting-Started/#wio-terminal-classroom でなんか最初のほうのやることあるっぽいけど、動画じゃなくて文字にしてほしい……。
uploadができない時
大抵ぬるぽで死んで固まっている。
2回resetすればいける(bootloader modeになるから?)。
RawImage.h
RawImage.h
#pragma once
#include<stdint.h>
#include<SD/Seeed_SD.h>
/*
USAGE:
// when use 8bit color.
Raw8 * img8 = newImage<uint8_t>("path to sd card image.");
// when use 16bit color.
Raw16 * img16 = newImage<uint16_t>("path to sd card image.");
// do some drawing.
// img8->draw();
// remember release it
img8->release();
img16->release();
*/
extern TFT_eSPI tft;
template<class type>
struct RawImage{
type * ptr(){
return (type *)(this + 1);
}
type get(int16_t x, int16_t y){
return this->ptr()[y * width() + x];
}
void draw(size_t x = 0, size_t y = 0){
tft.pushImage(x, y, width(), height(), ptr());
}
void release(){
delete [] this;
}
int16_t width(){ return _width; }
int16_t height(){ return _height; }
private:
int16_t _width;
int16_t _height;
};
typedef RawImage<uint8_t> Raw8;
typedef RawImage<uint16_t> Raw16;
template<class type>
RawImage<type> * newImage(const char * path){
typedef RawImage<type> raw;
File f = SD.open(path, FILE_READ);
if (!f){
return nullptr;
}
int32_t size = f.size();
raw * mem = (raw *)new uint8_t[size];
if (mem == nullptr){
return nullptr;
}
f.read(mem, size);
f.close();
return mem;
}
template<class type>
void drawImage(const char * path, size_t x = 0, size_t y = 0){
auto img = newImage<type>(path);
img->draw(x, y);
img->release();
}
このソースコードバグってない?
newImage
の中で、 raw * mem = (raw *)new uint8_t[size]
とファイルサイズ分確保してそれを RawImage
型にcastしているが、 draw
から呼ばれている ptr
では (type *)(this + 1)
を返している。 が、
f.read
で mem
の先頭から(ここの実装知らないけど多分)memに書いている。 new
する際に sizeof(raw) + size
分確保して、 mem + 1
にreadしないといけないのでは? なんか上記のようにしたら1行は出たけどばぐっとるな。
draw
の中で width
と height
を呼んでるけどこれが初期化されるタイミングないのか。なんか適当に以下のように修正した。
interface変わったけど……。
sizeof(raw) + size
取ってきてplacement newしてもいいか? と思ったけど、どうせ tft.pushImage
にはptrの形で渡ってるなら連続領域で取ってもそんなにメリット無い気がするし、大人しく2段階に割り付ける。 どうせ他の割り込みがなければ連続領域になるのではないか?(未確認)(順序は違うだろうけど)
myRawImage.h
#pragma once
#include<stdint.h>
#include<SD/Seeed_SD.h>
/*
USAGE:
// when use 8bit color.
Raw8 * img8 = newImage<uint8_t>("path to sd card image.");
// when use 16bit color.
Raw16 * img16 = newImage<uint16_t>("path to sd card image.");
// do some drawing.
// img8->draw();
// remember release it
img8->release();
img16->release();
*/
extern TFT_eSPI tft;
template<class type>
struct RawImage {
type * ptr() { return (type *)val_; }
type get(int16_t x, int16_t y) { return this->ptr()[y * width() + x]; }
void draw(size_t x = 0, size_t y = 0) { tft.pushImage(x, y, width(), height(), ptr()); }
void release() { delete[] val_; }
int16_t width(){ return width_; }
int16_t height(){ return height_; }
RawImage(uint8_t* val, int16_t width, int16_t height) : val_{val}, width_{width}, height_{height} {}
private:
uint8_t* val_;
int16_t width_;
int16_t height_;
};
typedef RawImage<uint8_t> Raw8;
typedef RawImage<uint16_t> Raw16;
template<class type>
RawImage<type> * newImage(const char * path, int16_t width, int16_t height){
typedef RawImage<type> raw;
File f = SD.open(path, FILE_READ);
if (!f){
return nullptr;
}
int32_t size = f.size();
uint8_t* buf = new uint8_t[size];
if (!buf){
return nullptr;
}
f.read(buf, size);
f.close();
return new raw(buf, width, height);
}
template<class type>
void drawImage(const char * path, size_t x = 0, size_t y = 0){
// auto img = mynewImage<type>(path, 0, 0); // FIXME
//img->draw(x, y);
//img->release();
}
bmp_converter
を使うのがダルいからimagemagickでなんとかできないか? とか思って適当に変換してみてるけどバグっているが、今まではぬるぽで死んでたのと比べてそんなことはない……。 チュートリアルにあるライブラリがこんな盛大にバグってるなんてことある?
↓ で変換して出したらうまいこといっていた。
いい感じ。
bmp_converter
ms paintで保存しろ とか言っててめんどくさい……。
ようするにピクセルの色単位でつっこんでけばいいっぽいのでgoで適当に書いた。
ある程度書いたらCopilotくんがどんどん補完してくれて便利。
color.Color
の RGBA()
は16bitで値を返すとこだけ若干ハマった。comment
RGBA returns the alpha-premultiplied red, green, blue and alpha values
for the color. Each value ranges within [0, 0xffff], but is represented
by a uint32 so that multiplying by a blend factor up to 0xffff will not
overflow.
uint32
なら32bitなのかと思うじゃん……。