猫とコード

化学メーカーでweb開発している猫大好きエンジニアの備忘録です。

JavaScriptでクリップボードの画像をリサイズしてキャンバスに張り付ける

いい参考コードが見当たらず苦戦していましたが,ChatGPTに聞いたら一発でした.

チャットGPTに聞いたこと

JavaScriptでクリップボードから画像を張り付けてCanvasでアスペクト比は変えずに縦横どちらかの最大の大きさが800px以下になるように変形し,Canvasサイズも同じ縦横の大きさになるように描画するコードを教えて

動くコードでしたがちょっとニュアンスが違い,実装したい仕様とことなりました.返答のコードはCanvasサイズを800pxにするコードか,Canvaサイズを変えずに中の画像を長辺が800px以下にするコードの2通りの返答でした.

二つを組み合わせて下記のようにしました 下記で動きます.

動くコードも嬉しいけど何よりコメントが本当にうれしいです. 全部にはさすがに付けないけど,ここは他の人(半年後の自分含む)が見たら理解に数秒かかるだろうな~というポイントにコメント残すようにしているのでデフォルトでしっかりコメント付けてくれるのがうれしいです.

<!DOCTYPE html>
<html>
<body>
  <canvas id="canvas"></canvas>

  <script>
    // クリップボードから画像を貼り付けた時に実行される関数
    function handlePaste(event) {
      var items = event.clipboardData.items;

      // 画像がクリップボードに存在する場合
      if (items && items.length) {
        var file = null;

        // 画像データを探す
        for (var i = 0; i < items.length; i++) {
          if (items[i].type.indexOf('image') !== -1) {
            file = items[i].getAsFile();
            break;
          }
        }

        if (file !== null) {
          var reader = new FileReader();

          // ファイルの読み込み完了時に実行される関数
          reader.onload = function(event) {
            var image = new Image();
            image.onload = function() {
              var canvas = document.getElementById('canvas');
              var context = canvas.getContext('2d');

              var aspectRatio = image.width / image.height;
              var maxWidth = 800;
              var maxHeight = 800;

              if (aspectRatio > 1) {
                // 横長の場合
                var newWidth = Math.min(image.width, maxWidth);
                var newHeight = newWidth / aspectRatio;

                if (newHeight > maxHeight) {
                  newHeight = maxHeight;
                  newWidth = newHeight * aspectRatio;
                }
              } else {
                // 縦長または正方形の場合
                var newHeight = Math.min(image.height, maxHeight);
                var newWidth = newHeight * aspectRatio;

                if (newWidth > maxWidth) {
                  newWidth = maxWidth;
                  newHeight = newWidth / aspectRatio;
                }
              }

              // キャンバスのサイズを設定する
              canvas.width = newWidth;
              canvas.height = newHeight;
              
              // 画像の縦横比を保持しながらキャンバスに描画する
              context.drawImage(image, 0, 0, newWidth, newHeight);
            };
            image.src = event.target.result; // 読み込んだファイルのデータURL
          };

          // ファイルを読み込む
          reader.readAsDataURL(file);
        }
      }
    }

    // クリップボードからの貼り付けイベントを検知し、handlePaste関数を実行する
    document.addEventListener('paste', handlePaste);
  </script>
</body>
</html>