質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
canvas

HTML5の<canvas>要素用のタグです。CanvasはHTML5から導入された、二次元の図形描写が可能な要素です。

Ruby on Rails 4

Ruby on Rails4はRubyによって書かれたオープンソースのウェブフレームワークです。 Ruby on Railsは「設定より規約」の原則に従っており、効率的に作業を行うために再開発を行う必要をなくしてくれます。

Q&A

解決済

1回答

1929閲覧

canvasの画像をデータベースに保存したい

hokosugi

総合スコア63

canvas

HTML5の<canvas>要素用のタグです。CanvasはHTML5から導入された、二次元の図形描写が可能な要素です。

Ruby on Rails 4

Ruby on Rails4はRubyによって書かれたオープンソースのウェブフレームワークです。 Ruby on Railsは「設定より規約」の原則に従っており、効率的に作業を行うために再開発を行う必要をなくしてくれます。

1グッド

0クリップ

投稿2018/09/13 02:34

前提・実現したいこと

railsでform_forを利用してcanvasの画像をデータベースに保管したい。

発生している問題

参照ブログをコピペして(coffeescriptが効かなかったのでjavascriptに変えています。)実行しています。しかし上手く行っておらずalertメソッドで
url = canvas.toDataURL();
までは上手く行っていることはわかっています。ただデータのみ取得する配列指定(canvas[0])が効きません。
そこでurl全体を表示しましたが、返ってくるパラメーターのbase64以下が長すぎるように感じます。

Parameters: {"utf8"=>"✓", "authenticity_token"=>"nRyR697wqvq8COSPwjWoODBOcS45JGpx/2cB7x8jBrlKk7ZWLB7i1oT5/r3MbfC4XUG9IzUvBWo9R3OfgZ2M/g==", "picture"=>{"remark"=>"", "image_url"=>"data:image/png;base64, iVBORw0KGgoAAAANSUhEUgAAAoAAAAHgCAYAAAA10dzkAAAgAElEQVR4Xoy92ZJkW3Idts8QkVnVE/Ck//8IGWWUBHSDaoDSB8hEmUSCIB5JkH1v3RziTLI1以下続く

error

1ActiveRecord::StatementInvalid in CameraController#create 2Mysql2::Error: Data too long for column 'image_url' at row 1: INSERT INTO `pictures` (`image_url`, `remark`, `created_at`, `updated_at`) VALUES

javascript

1//当該部分 2$(function() { 3(省略) 4 $('#save-button').click(function(){ 5 var canvas = document.getElementById('canvas'); 6 url = canvas.toDataURL(); 7 alert(url); 8 $('#picture_image_url').val(''); 9 $('#picture_image_url').val(url); 10 $('#new_picture').submit(); 11 }) 12})

html

1//全文 2<!DOCTYPE html> 3<html> 4<head> 5 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 6 <link rel="stylesheet" href="style.css"> 7 <title>Webカメラの映像を画像化</title> 8</head> 9<body> 10 <h2>Video</h2> 11 <video id="camera" autoplay></video> 12 <button id="start">start</button> 13 <h2>Canvas</h2> 14 <canvas id="canvas"></canvas> 15 <h2>Img</h2> 16 <img id="img"> 17 <script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script> 18 <script type="text/javascript" src="./script.js"></script> 19 20 <%= form_for(@picture, url: 'camera') do |f| %> 21 <%= f.text_field :remark %><br> 22 <%= f.hidden_field :image_url, :value => "" %> 23 <!--<%= f.submit %>--> 24 <% end %> 25 <button id="save-button">保存</button> 26</body> 27</html>

controller

1class CameraController < ApplicationController 2 3 def take 4 @picture = Picture.new 5 6 end 7 8 def create 9 10 @picture = Picture.new(picture_params) 11 @picture.image_url = params['picture']['image_url'] 12 if @picture.save 13 redirect_to camera_path, notice: '保存しました。' 14 else 15 render :take 16 end 17 end 18 19 20 private 21 def picture_params 22 params.require(:picture).permit(:image_url, :remark) 23 end 24end

model

1class CreatePictures < ActiveRecord::Migration 2 def change 3 create_table :pictures do |t| 4 t.text :image_url 5 t.string :remark 6 t.timestamps null: false 7 end 8 end 9end

試したこと

カラムの形式がtextでもエラーが出るのでデータの長さを取得(約67万文字、間違えているのかもしれませんが・・・)
Atom Runner: untitled
670380

text形式が65000半角文字までということなのでエラーも仕方ないのでしょうか?

canvasの品質を落とすと文字数が落ちるのではないかと
url = canvas.toDataURL('image/png', 0.2);
としましたがむしろ増えて69万文字。
Atom Runner: untitled
694079

dataURIスキームは約30%ほど画像サイズから大きくなるとのこと、但しtext形式の約10倍もあるデータサイズから考えると30%増が原因とは考えられない。

あと考えられるのは画像サイズ自体がでかすぎて使えないこと?
ただ、いろいろなブログで書かれている画像サイズなのでそうでもないような気もする。
ブログから拝借して画像サイズを指定しました。

javascript

1 //videoの縦幅横幅を取得 2 var w = video.offsetWidth; 3 var h = video.offsetHeight; 4 5 //同じサイズをcanvasに指定 6 canvas.setAttribute("width", w); 7 canvas.setAttribute("height", h);

よろしくおねがいします

このように画像取得でデータが長すぎるエラーが出た場合、

1、データ取得のやり方自体を間違えている
2、データ取得は問題ないがデータが長すぎるので諦める
3、canvas.dataURIなんか使ってるからだ、もっといい方法がある!

の3択だと思いますが、宜しければご指導お願いします。

NightitWy👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

自己解決

なんとか自己解決しました。
url = canvas.toDataURL();

url = canvas.toDataURL('image/jpeg');
にするだけ。これだけで画像データが圧縮されるようです。非可逆圧縮というそうです。
これに加えて
var w = video.offsetWidth;
var h = video.offsetHeight;

video.width = 400
var w = video.width;
video.height = 200
var h = video.height;
として画像を縮小すると1万文字程度まで低減出来て、無事データベースに格納できました。

投稿2018/09/14 10:40

hokosugi

総合スコア63

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問