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

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

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

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

JavaScript

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

Q&A

解決済

1回答

135閲覧

JavaScriptでcanvasの画像を取得する際に拡張子が正しく適用できない

numin

総合スコア34

canvas

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

JavaScript

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

0グッド

1クリップ

投稿2025/03/21 13:57

実現したいこと

作成中の画像リサイズアプリにて、アップロードされた時のものと同じ拡張子で処理後の画像を取得すること

前提

現在、HTML・JavaScriptを使って画像リサイズツールを作成しています。

そのうちアップロードされた画像のサイズを変更する処理そのものは問題なく実行できているのですが、canvasから処理後の画像を取得しダウンロードリンクを生成する際に正しい拡張子を適用することができず困っています。

もし原因・解決方法をご存知でしたら、ご教示いただけますと幸いです。

発生している問題・エラーメッセージ

本来は投稿された画像ファイルの拡張子を変数extに保存し出力ファイル名「newFileName」にもそのまま適用させたいと考えているのですが、なぜか出力される画像の拡張子が毎回pngになってしまいます。

該当のソースコード

JavaScript

1let originalWidth = 0; 2let originalHeight = 0; 3let aspectRatio = 1; 4 5function loadImage() { 6 // 投稿された画像 7 let fileInput = document.getElementById('imageInput').files[0]; 8 if (!fileInput) return; 9 10 let reader = new FileReader(); 11 reader.readAsDataURL(fileInput); 12 13 reader.onload = function(event) { 14 let img = new Image(); 15 img.src = event.target.result; 16 17 img.onload = function() { 18 originalWidth = img.width; 19 originalHeight = img.height; 20 aspectRatio = originalWidth / originalHeight; 21 22 // 幅・高さの入力フィールドに投稿された画像の元のサイズを自動挿入 23 document.getElementById('widthInput').value = originalWidth; 24 document.getElementById('heightInput').value = originalHeight; 25 26 // サイズ変更方法のSelect要素を表示 27 document.getElementById('resizeType').style.visibility = "visible"; 28 document.getElementById('resizeLabel').style.visibility = "visible"; 29 }; 30 }; 31} 32 33function updateInputFields() { 34 let resizeType = document.getElementById('resizeType').value; 35 let dimensionInputs = document.getElementById('dimensionInputs'); 36 let percentageInput = document.getElementById('percentageInput'); 37 38 // 選択されたサイズ変更方法に応じて入力フィールドの表示状態を変更 39 if (resizeType === "aspect") { 40 dimensionInputs.style.display = "block"; 41 percentageInput.style.display = "none"; 42 document.getElementById('widthInput').disabled = false; 43 document.getElementById('heightInput').disabled = false; 44 } else if (resizeType === "percentage") { 45 percentageInput.style.display = "block"; 46 dimensionInputs.style.display = "none"; 47 } else if (resizeType === "custom") { 48 dimensionInputs.style.display = "block"; 49 percentageInput.style.display = "none"; 50 document.getElementById('widthInput').disabled = false; 51 document.getElementById('heightInput').disabled = false; 52 } else { 53 dimensionInputs.style.display = "none"; 54 percentageInput.style.display = "none"; 55 } 56} 57 58// 縦横比維持の場合、幅・高さを自動調整 59function updateHeightAspect() { 60 let resizeType = document.getElementById('resizeType').value; 61 let widthInput = document.getElementById('widthInput'); 62 let heightInput = document.getElementById('heightInput'); 63 64 if (resizeType === "aspect" && widthInput.value) { 65 heightInput.value = Math.round(widthInput.value / aspectRatio); 66 } 67} 68 69function updateWidthAspect() { 70 let resizeType = document.getElementById('resizeType').value; 71 let widthInput = document.getElementById('widthInput'); 72 let heightInput = document.getElementById('heightInput'); 73 74 if (resizeType === "aspect" && heightInput.value) { 75 widthInput.value = Math.round(heightInput.value * aspectRatio); 76 } 77} 78 79function resizeImage() { 80 let fileInput = document.getElementById('imageInput').files[0]; 81 if (!fileInput) { 82 alert("画像を正しくアップロードしてください。"); 83 return; 84 } 85 86 let resizeType = document.getElementById('resizeType').value; 87 let widthInput = document.getElementById('widthInput').value; 88 let heightInput = document.getElementById('heightInput').value; 89 let percentage = document.getElementById('percentage').value; 90 91 let reader = new FileReader(); 92 reader.readAsDataURL(fileInput); 93 94 reader.onload = function(event) { 95 let img = new Image(); 96 img.src = event.target.result; 97 98 img.onload = function() { 99 let canvas = document.getElementById('canvas'); 100 let ctx = canvas.getContext('2d'); 101 102 let newWidth, newHeight; 103 104 if (resizeType === "aspect") { 105 newWidth = parseInt(widthInput); 106 newHeight = parseInt(heightInput); 107 } else if (resizeType === "percentage") { 108 if (!percentage) { 109 alert("有効な数値を入力してください。"); 110 return; 111 } 112 let scale = percentage / 100; 113 newWidth = Math.round(originalWidth * scale); 114 newHeight = Math.round(originalHeight * scale); 115 } else if (resizeType === "custom") { 116 newWidth = parseInt(widthInput); 117 newHeight = parseInt(heightInput); 118 } 119 120 canvas.width = newWidth; 121 canvas.height = newHeight; 122 ctx.drawImage(img, 0, 0, newWidth, newHeight); 123 124 // ダウンロードリンクの設定 125 let downloadLink = document.getElementById('downloadLink'); 126 let originalName = fileInput.name; 127 const pos = originalName.lastIndexOf('.'); 128 let baseName = originalName.substring(0, pos) || originalName; 129 let ext = originalName.slice(pos + 1) 130 let newFileName = baseName + '-resized.' + ext; 131 // 下記「試したこと」にて説明 132 console.log(ext); 133 console.log(originalName); 134 downloadLink.download = newFileName; 135 let dataUrl = ''; 136 // 元の拡張子によって取得する画像のフォーマットを変更 137 if(ext == 'png' || ext == 'PNG') { 138 dataUrl = canvas.toDataURL("image/png"); 139 } else if(ext == 'jpg' || ext == 'JPG') { 140 dataUrl = canvas.toDataURL("image/jpg"); 141 } else if(ext == 'gif' || ext == 'GIF') { 142 dataUrl = canvas.toDataURL("image/gif"); 143 } else { 144 dataUrl = canvas.toDataURL(); 145 } 146 downloadLink.href = dataUrl; 147 downloadLink.style.display = "block"; 148 }; 149 }; 150}

試したこと

ext(元のファイルの拡張子)が正しく取得できていないのかと考え、上記の通り途中でextの内容をコンソールに出力させてみました。
ただこの時の出力結果は例えば「jpg」のように正しく出力されているのにも関わらず、やはりダウンロードされる画像は「example.jpg.png」というようにPNG形式に変更されてしまうため、未だ状況が把握できていない状況です。

以上です。
よろしくお願いいたします。

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

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

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

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

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

numin

2025/03/22 02:04

コメントを頂きありがとうございます。 ブラウザによっても互換性に違いがあるのですね。 今回はデスクトップ版Chromeとモバイル版Safari/Chromeを利用していたのですが、頂いたURLを元に、対応状況のチェックなども進めたいと思います。
guest

回答1

0

ベストアンサー

MIMEタイプをimage/jpgimage/jpegとするとどうでしょうか。

投稿2025/03/22 00:51

Lhankor_Mhy

総合スコア37358

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

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

numin

2025/03/22 02:09

的確且つご丁寧なご回答を頂き、ありがとうございます。 ご指摘いただいた通り、「image/jpg」⇨「image/jpeg」とする事でJPGアップロード時にも問題なく動作するようになりました。 引数が誤っていたら、拡張子の抜き出しができていても動かないはずですよね。 ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.32%

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

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

質問する

関連した質問