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

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

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

HTML5 (Hyper Text Markup Language、バージョン 5)は、マークアップ言語であるHTMLの第5版です。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

解決済

ウェブサイト内でカメラを使用して写真を撮影・ダウンロードする(スマホ用)

harapara
harapara

総合スコア37

HTML5

HTML5 (Hyper Text Markup Language、バージョン 5)は、マークアップ言語であるHTMLの第5版です。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

1回答

0評価

1クリップ

238閲覧

投稿2022/06/07 05:18

編集2022/07/06 03:07

ウェブサイト内でスマホの内カメを起動し、自身の顔を撮影→確認→ダウンロードが出来るようにしたいです。
(実際は顔の上にフレームをのせるので、顔以外は写りません。)
確認の部分でvideoを画像として切り取り、canvasに描画するのですが、その際(上下の黒フレーム分?)顔が伸びてしまいます。
何か良い方法ないでしょうか。。
スマホで使用したいのですが、カメラ比率は色々だと思っており、黒フレーム込みで切り取りたいです。

参考サイト:https://blog.katsubemakito.net/html5/camera2
参考サイト:https://github.com/dotnsf/html_camera_inside

html

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=645" /> <title>HTML Camera Inside</title> <script src="//code.jquery.com/jquery-2.0.3.min.js"></script> <style> * { margin: 0; padding: 0; box-sizing: border-box; } html, body { height: 100%; text-align: center; } body { background-color: #000; position: relative; } video { position: absolute; z-index: 10; } .container { width: 100%; max-width: 645px; position: relative; margin: auto; height: 100%; } #frame, #video, #dialog-outer { position: absolute; width: 645px; left: 0; top: 0; } #frame { z-index: 2; } #video { z-index: 10; background-color: black; } #dialog-outer { z-index: 30; background: #fff; height: 100%; position: fixed; text-align: center; display: none; } button { background-color: #fff; border: none; cursor: pointer; outline: none; padding: 0; appearance: none; padding: 0.5rem 2rem; font-size: 3rem; } #dialog-result-close { position: fixed; padding: 3px; right: 3px; top: 3px; font-size: 2rem; background-color: rgba(244, 244, 244, 0.8); } #btn-shutter { position: absolute; bottom: 3px; left: 50%; transform: translate(-50%, -50%); z-index: 30; } #dialog-result-dl { position: absolute; bottom: 4px; left: 0; width: 100%; } </style> </head> <body> <!-- video(visible) --> <div class="container" id="videoPreview" style="text-align: center"> <h4>Video Preview</h4> <canvas id="frame" width="645" height="860"></canvas> </div> <!-- canvas(invisible) --> <div class="container" id="canvasPreview" style="text-align: center; display: none" > <h4>Canvas Preview</h4> </div> <!-- シャッター --> <div id="shutter-inner"> <button id="btn-shutter" type="button">撮影</button> </div> <!-- 最終結果 --> <div id="dialog-outer"> <div id="dialog-result" class="dialog"> <div id="dialog-result-close">Close</div> <p><canvas id="result" width="645" height="860"></canvas></p> <button id="dialog-result-dl" type="button">download</button> </div> <!-- NowLoading --> <div id="dialog-nowloading" class="dialog">...Now Loading</div> </div> <script> var cameraSize = { w: 645, h: 860 }; var canvasSize = { w: 645, h: 860 }; var resolution = { w: 1080, h: 720 }; var video = null; var media = null; var canvas = null; var ctx = null; const FRAME = document.querySelector("#frame"); $(function () { //. video video = document.createElement("video"); video.id = "video"; video.width = cameraSize.w; video.height = cameraSize.h; video.setAttribute("autoplay", true); //. #1 video.setAttribute("muted", ""); //. #1 video.setAttribute("playsinline", ""); //. #1 document.getElementById("videoPreview").appendChild(video); //. media var data = { audio: false, //. no voice/mic video: { facingMode: "user", //. front width: { ideal: resolution.w }, height: { ideal: resolution.h }, }, }; media = navigator.mediaDevices .getUserMedia(data) .then(function (stream) { video.srcObject = stream; }) .then(function (err) {}); //. canvas canvas = document.createElement("canvas"); canvas.id = "canvas"; canvas.width = canvasSize.w; canvas.height = canvasSize.h; document.getElementById("canvasPreview").appendChild(canvas); //. context ctx = canvas.getContext("2d"); document.querySelector("#btn-shutter").addEventListener("click", () => { // 画像の生成 onShutter(); // カメラ映像から静止画を取得 concatCanvas("#result", ["#canvas", "#frame"]); // フレームと合成 // 最終結果ダイアログを表示 setTimeout(() => { // 演出目的で少しタイミングをずらす dialogShow("#dialog-result"); }, 300); }); document .querySelector("#dialog-result-dl") .addEventListener("click", (e) => { canvasDownload("#result"); }); //----------------------------- // ダイアログ //----------------------------- // 閉じるボタン document .querySelector("#dialog-result-close") .addEventListener("click", (e) => { // video.play(); dialogHide("#dialog-result"); }); }); /** * シャッターボタンをクリック * * @return {void} **/ function onShutter() { const STILL = document.querySelector("#canvas"); // <canvas> const VIDEO = document.querySelector("#video"); // <video> const ctx = canvas.getContext("2d"); // 前回の結果を消去 ctx.clearRect(0, 0, STILL.width, STILL.height); // videoを画像として切り取り、canvasに描画 ctx.drawImage(VIDEO, 0, 0, STILL.width, STILL.height); } /** * Canvas合成 * * @param {string} base 合成結果を描画するcanvas(id) * @param {array} asset 合成する素材canvas(id) * @return {void} */ async function concatCanvas(base, asset) { const canvas = document.querySelector(base); const ctx = canvas.getContext("2d"); for (let i = 0; i < asset.length; i++) { const image1 = await getImagefromCanvas(asset[i]); ctx.drawImage(image1, 0, 0, canvas.width, canvas.height); } } /** * Canvasを画像として取得 * * @param {string} id 対象canvasのid * @return {object} */ function getImagefromCanvas(id) { return new Promise((resolve, reject) => { const image = new Image(); const ctx = document.querySelector(id).getContext("2d"); image.onload = () => resolve(image); image.onerror = (e) => reject(e); image.src = ctx.canvas.toDataURL(); }); } /** * ダイアログを表示 * * @param {string} id **/ function dialogShow(id) { document.querySelector("#dialog-outer").style.display = "block"; document.querySelector(id).style.display = "block"; } /** * ダイアログを非表示 * * @param {string} id **/ function dialogHide(id) { document.querySelector("#dialog-outer").style.display = "none"; document.querySelector(id).style.display = "none"; } </script> </body> </html>

良い質問の評価を上げる

以下のような質問は評価を上げましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

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

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

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

teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

  • プログラミングに関係のない質問
  • やってほしいことだけを記載した丸投げの質問
  • 問題・課題が含まれていない質問
  • 意図的に内容が抹消された質問
  • 過去に投稿した質問と同じ内容の質問
  • 広告と受け取られるような投稿

評価を下げると、トップページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

まだ回答がついていません

会員登録して回答してみよう

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

ただいまの回答率
87.20%

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

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

質問する

関連した質問

同じタグがついた質問を見る

HTML5

HTML5 (Hyper Text Markup Language、バージョン 5)は、マークアップ言語であるHTMLの第5版です。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。