Chrome拡張機能_WindowsとMacでの拡大率の扱いの違いにハマった話

はじめに

Chrome拡張機能を自作していて、要素をスクリーンショットとしてキャプチャする処理を書いていたところ、WindowsとMacで挙動が異なる問題に遭遇しました。
同じコードでも Windowsでは正しくキャプチャできないケース があり、調べてみると「ディスプレイの拡大率」と「ブラウザのズーム倍率」の扱いがOSごとに違うのが原因でした。

本記事では、私がハマった経緯と、最終的にどのような対処をしたかを紹介します。

背景

今回のコードは、任意のDOM要素をキャプチャするために canvas を使ってスクリーンショットを生成するものです。
GitHubに公開している拡張はこちらです:

キャプチャのために要素の座標やサイズを計算しています。当初開発はMacで行っていましたが、リリース後にWindows上で正常にキャプチャができないことが発覚したため、調べていました。

問題の発生

試した環境は以下の通りです:

  • Mac: ディスプレイの拡大率 = 100%、ブラウザのズーム倍率 = 100% → 問題なし
  • Windows: ディスプレイの拡大率 = 125%、ブラウザのズーム倍率 = 100% → キャプチャ位置がずれる

つまり、Windowsではシステム側の拡大率(DPIスケーリング)が影響するのです。

調査結果

友人に相談したところ、Windowsの場合はシステム設定側の問題でズレることがあるとアドバイスをいただき、目星をつけることができました。

JavaScriptから取得できる値を確認したところ:

  • window.devicePixelRatio
    → システムの拡大率(DPIスケーリング)を反映
  • chrome.tabs.getZoom()window.visualViewport.scale
    → ブラウザのズーム倍率を反映

Macの場合はブラウザの拡大率のみ取得すれば問題ありません。(OS側でうまくやっているようです)
しかし、Windowsは OS側の拡大率とブラウザズームの両方が絡むため、システム拡大率も反映した値を出すwindow.devicePixelRatioを使用する必要があると考えました。

対応方法

**Windows環境ではOSの拡大率を考慮した、“devicePixelRatio"を利用して算出することにしました。 該当部分のコードは以下のようにしています(抜粋):

this.isWindows = /Windows/.test(navigator.userAgent);
// Windowsの場合: devicePixelRatioを使用
if (this.isWindows) {
  const devicePixelRatio = window.devicePixelRatio;
  if (devicePixelRatio && devicePixelRatio > 0) {
    console.log('Windows detected, using devicePixelRatio:', devicePixelRatio);
    return devicePixelRatio;
  } else {
    console.warn('devicePixelRatio not available, falling back to chrome.runtime.sendMessage');
  }
}

これで、WindowsでもMacでもズレなくキャプチャできるようになりました。

まとめ

  • Macではブラウザのズーム倍率のみ考慮すればOK
  • Windowsではディスプレイ拡大率とズーム倍率の両方を考慮する必要あり

小さな違いですが、クロスプラットフォーム対応を考えると意外と重要なポイントでした。
“windows mac 拡張機能 座標"で検索してもなかなか出てこなかったので、記事作成しました。
同じように「スクショがズレる…」と悩んでいる方の参考になれば幸いです。

参考