概要
前回 drawingboard.js に入門してみました
今回はサーバサイドに作成した画像を保存してみます
サーバサイドは Ruby で実装します
環境
- macOS 11.6.2
- Ruby 3.0.3p157
- sinatra 2.1.0
- drawingboard.js 0.4.2
config.ru
require './app'
run TestWeb
app.rb
require 'sinatra'
require 'base64'
class TestWeb < Sinatra::Base
get '/' do
erb :index
end
post '/' do
filename = params[:filename]
image = params[:image]
image = Base64.decode64(image.gsub('data:image/png;base64,', '').gsub(/\s/, '+'))
File.open("/tmp/#{filename}.png", 'wb') do |file|
file.write(image)
'ok'
end
end
end
index.erb
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width">
<script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/drawingboard.js/0.4.2/drawingboard.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/drawingboard.js/0.4.2/drawingboard.min.css">
<style data-example="2">
#board1 {
width: 400px;
height: 400px;
}
</style>
</head>
<body>
<div class="board" id="board1"></div>
<input id="filename" type="text" value="image1" />
<button id="save">Save</button>
<script data-example="2">
var board1 = new DrawingBoard.Board('board1', {
background: "#000000",
color: "#ffffff",
size: 30,
fillTolerance: 150,
controls: [
{ Size: { type: "range", min: 12, max: 42 } },
{ Navigation: { back: true, forward: true } },
'DrawingMode',
'Color'
],
webStorage: 'local',
droppable: true
});
board1.addControl('Download');
board1.downloadImg = function() {
var img = this.getImg();
img = img.replace("image/png", "image/octet-stream");
var link = document.createElement('a');
link.download = "download.png";
link.href = img;
link.click();
};
$('#save').on('click', function(e) {
var img = board1.getImg();
var filename = $("#filename").val();
$.ajax({
type: "POST",
url: "/",
enctype: 'multipart/form-data',
data: "image=" + img + '&filename=' + filename,
success: function(msg){
alert( "Data Saved: " + msg );
},
error: function(XMLHttpRequest, textStatus, errorThrown) {
alert("some error");
}
});
});
</script>
</body>
</html>
ちょっと解説
画像情報を送信する場合は base64 エンコードされたデータを文字列で送信します
わざわざバイナリ変換してファイルとして送信する方法もありますが文字列のほうが扱いが楽なので文字列のまま使います
base64 の文字列を送信する場合は ajax を使います
POST で multipart/form-data として送信します
こうすることで一緒にファイル名も送信できます
Ruby (sinatra) 側ではフォームデータとして画像データとファイル名を取得します
それぞれ params から文字列として取得できます
画像データは不要な文字列をエスケープしスペースをプラスに置換します
あとは Base64.decode しファイルをバイナリ形式で保存すれば OK です
実際にファイル化するのが嫌な場合は Redis などに文字列としてそのまま保存すると良いかなと思います
最後に
なぜか ajax から受け取った画像の base64 データがサーバサイドだと一部置換されているのでそこをちゃんと補完してあげることを忘れないようにしましょう
0 件のコメント:
コメントを投稿