やりかた
主に2つある,基本的には上で事足りるよね…?
matlab
純正関数を使う
matlab.net.base64encode
とmatlab.net.base64decode
を直で叩く
そもそも画像データを読み込んで云々という動作させるには工夫が必要,データと型の扱いとか…
org.apache
を拝借する
org.apache.commons.codec.binary.base64
をインスタンス化する
ただなんでJavaのライブラリが使えているのかよくわからん,R2022aで動いたけどこれはおま環かもしれないので要注意
あとmatlab
との食い合わせが悪いかもしれないので工夫が必要
使用例
やること
-
html
でData URI Scheme
を出す-
Chrome
なら見れるはず
-
- encode/decodeで元のファイルを復元する
-
そのまま
slack
のwebhookにも送りつけてみる-
type
にはmrkdwn
を指定する - 試したい人はapiを用意してね
-
clear;
imgUrl = 'test.png';
fid = fopen(imgUrl);
fbt = fread(fid);
fclose(fid);
% With Apache
base64Coder = org.apache.commons.codec.binary.Base64;
fbtB64apa = uint8(base64Coder.encode(uint8(fbt)));
fbtB64apaChr = char(fbtB64apa.');
revfbtapa = double(typecast(base64Coder.decode(fbtB64apa),'uint8'));
newfid=fopen('test1Apache.png','w+');
fwrite(newfid,revfbtapa);
fclose(newfid);
% With Matlab
fbtB64matChr = matlab.net.base64encode(uint8(fbt));
revfbtmat = double(matlab.net.base64decode(fbtB64matChr).');
newfid=fopen('test1Matlab.png','w+');
fwrite(newfid,revfbtmat);
fclose(newfid);
% html base64 uri data scheme
html = '<head></head><body><img src="data:image/png;base64,'+string(fbtB64apaChr)+'"></body>'; % easy html style
newfid=fopen('test1.html','w+');
fwrite(newfid,html);
fclose(newfid);
% try to send Slack webhook
url = 'https://hooks.slack.com/services/xxx/yyy/zzz'; % your Webhook API url
content.type="html";
content.text = '<img src="data:image/png;base64,'+string(fbtB64apaChr)+'">'; % easy markdown style
payload = jsonencode(content);
options = weboptions('CharacterEncoding','UTF-8','UserAgent','matlab_simulink','Timeout',8);
webwrite(url,payload,options);
どうなるか
こうなれば良い,matlab
とapache
で結果が一致するはず
html
はブラウザで画像が見えていればOK
フォルダを見て画像が復元されていればOK
slack
はクッソ長い文字列しか見えない,そもそもData URI Schemeに非対応か,もしくは文字数制限でインタプリタが動作しないか…
やはりどうしても画像投稿用のAPIを使う必要があるらしいな?
matlab
の問題点
自前でuint8(binary)
しないとダメ,内部で変換してくれるらしいのだが恐らくtypecast(binary,'uint8')
をされている
画像データの読み込み時にdouble
のarray
になるので,それをcast
しながらdecode
してはいけない
apache
の問題点
恐らくちゃんとしたバイナリ列を返してくれるが,matlab
側がint8
で受け取るためオーバーフローみたいになる
ここではuint8
にcast
する必要がある