画像保護機能ガイド

🛡️ 概要

このサイトでは、プロフィール写真などの個人画像を不正利用から保護するための複数の技術的対策を実装しています。

📋 実装された保護機能

1. 技術的保護

  • ✅ 右クリック防止
  • ✅ ドラッグ&ドロップ防止
  • ✅ 選択・コピー防止
  • ✅ 印刷ときの透かし追加
  • ✅ 開発者ツール検出・警告
  • ✅ Canvas による画像難読化

2. 視覚的保護

  • ✅ 動的透かし(著作権表示)
  • ✅ 画像オーバーレイ
  • ✅ 警告メッセージ表示

3. 法的保護

  • ✅ 著作権表示の自動追加
  • ✅ 利用規約の明示

🔧 使用方法

保護された画像の表示

<!-- 保護された画像表示コンポーネント -->
<div class="protected-image-container" data-image="/images/profile/profile.jpg">
  <div class="image-wrapper">
    <!-- 透明なオーバーレイで右クリック防止 -->
    <div
      class="image-overlay"
      oncontextmenu="return false;"
      ondragstart="return false;"
      onselectstart="return false;"
    ></div>
    <!-- 実際の画像 -->
    <img
      src="/images/profile/profile.jpg"
      alt="説明文"
      class="protected-image"
      oncontextmenu="return false;"
      ondragstart="return false;"
      onselectstart="return false;"
      style="pointer-events: none; user-select: none"
    />
  </div>
  <!-- 透かし文字 -->
  <div class="watermark">© F.K.</div>
</div>

<style>
  .protected-image-container {
    position: relative;
    display: inline-block;
    max-width: 100%;
  }

  .image-wrapper {
    position: relative;
    display: inline-block;
  }

  .protected-image {
    max-width: 100%;
    height: auto;
    border-radius: 10px;
    box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
    /* 右クリック・ドラッグ防止 */
    -webkit-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;
    -webkit-user-drag: none;
    -webkit-touch-callout: none;
  }

  .image-overlay {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    z-index: 10;
    cursor: default;
  }

  .watermark {
    position: absolute;
    bottom: 5px;
    right: 5px;
    background: rgba(0, 0, 0, 0.4);
    color: white;
    padding: 2px 6px;
    font-size: 8px;
    border-radius: 2px;
    pointer-events: none;
    z-index: 15;
    opacity: 0.3;
  }

  /* 印刷時の保護 */
  @media print {
    .protected-image-container::after {
      content: "© Dr. Fumiyoshi Kobayashi (小林 史佳) - Unauthorized reproduction prohibited";
      position: absolute;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
      background: rgba(255, 255, 255, 0.9);
      padding: 2px;
      font-weight: normal;
      color: #333;
      z-index: 20;
    }
  }

  /* 開発者ツール対策(完全ではないが抑制効果あり) */
  @media screen {
    .protected-image {
      background: url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTAwIiBoZWlnaHQ9IjEwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48dGV4dCB4PSI1MCIgeT0iNTAiIGZvbnQtZmFtaWx5PSJBcmlhbCIgZm9udC1zaXplPSIxNCIgZmlsbD0iIzk5OSIgdGV4dC1hbmNob3I9Im1pZGRsZSIgZG9taW5hbnQtYmFzZWxpbmU9Im1pZGRsZSI+wqkgRnVtaXlvc2hpPC90ZXh0Pjwvc3ZnPg==")
        no-repeat center;
    }
  }
</style>

<script>
  // JavaScript による追加保護
  document.addEventListener("DOMContentLoaded", function () {
    // 右クリック防止
    document
      .querySelectorAll(".protected-image-container")
      .forEach(function (container) {
        container.addEventListener("contextmenu", function (e) {
          e.preventDefault();
          console.log("Image is protected - Right click disabled");
          return false;
        });

        // ドラッグ防止
        container.addEventListener("dragstart", function (e) {
          e.preventDefault();
          return false;
        });

        // 選択防止
        container.addEventListener("selectstart", function (e) {
          e.preventDefault();
          return false;
        });
      });

    // F12 キー(開発者ツール)の検出
    document.addEventListener("keydown", function (e) {
      if (
        e.keyCode === 123 || // F12
        (e.ctrlKey && e.shiftKey && e.keyCode === 73) || // Ctrl+Shift+I
        (e.ctrlKey && e.shiftKey && e.keyCode === 67) || // Ctrl+Shift+C
        (e.ctrlKey && e.keyCode === 85)
      ) {
        // Ctrl+U
        console.log("Developer tools access detected");
        // 完全に防ぐことはできないが、警告を出すことは可能
      }
    });
  });
</script>

通常画像との比較

<!-- ❌ 通常の画像(保護なし) -->
<img src="/images/photo.jpg" alt="説明文">

<!-- ✅ 保護された画像 -->
<!-- 保護された画像表示コンポーネント -->
<div class="protected-image-container" data-image="/images/photo.jpg">
  <div class="image-wrapper">
    <!-- 透明なオーバーレイで右クリック防止 -->
    <div
      class="image-overlay"
      oncontextmenu="return false;"
      ondragstart="return false;"
      onselectstart="return false;"
    ></div>
    <!-- 実際の画像 -->
    <img
      src="/images/photo.jpg"
      alt="説明文"
      class="protected-image"
      oncontextmenu="return false;"
      ondragstart="return false;"
      onselectstart="return false;"
      style="pointer-events: none; user-select: none"
    />
  </div>
  <!-- 透かし文字 -->
  <div class="watermark">© F.K.</div>
</div>

<style>
  .protected-image-container {
    position: relative;
    display: inline-block;
    max-width: 100%;
  }

  .image-wrapper {
    position: relative;
    display: inline-block;
  }

  .protected-image {
    max-width: 100%;
    height: auto;
    border-radius: 10px;
    box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
    /* 右クリック・ドラッグ防止 */
    -webkit-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;
    -webkit-user-drag: none;
    -webkit-touch-callout: none;
  }

  .image-overlay {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    z-index: 10;
    cursor: default;
  }

  .watermark {
    position: absolute;
    bottom: 5px;
    right: 5px;
    background: rgba(0, 0, 0, 0.4);
    color: white;
    padding: 2px 6px;
    font-size: 8px;
    border-radius: 2px;
    pointer-events: none;
    z-index: 15;
    opacity: 0.3;
  }

  /* 印刷時の保護 */
  @media print {
    .protected-image-container::after {
      content: "© Dr. Fumiyoshi Kobayashi (小林 史佳) - Unauthorized reproduction prohibited";
      position: absolute;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
      background: rgba(255, 255, 255, 0.9);
      padding: 2px;
      font-weight: normal;
      color: #333;
      z-index: 20;
    }
  }

  /* 開発者ツール対策(完全ではないが抑制効果あり) */
  @media screen {
    .protected-image {
      background: url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTAwIiBoZWlnaHQ9IjEwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48dGV4dCB4PSI1MCIgeT0iNTAiIGZvbnQtZmFtaWx5PSJBcmlhbCIgZm9udC1zaXplPSIxNCIgZmlsbD0iIzk5OSIgdGV4dC1hbmNob3I9Im1pZGRsZSIgZG9taW5hbnQtYmFzZWxpbmU9Im1pZGRsZSI+wqkgRnVtaXlvc2hpPC90ZXh0Pjwvc3ZnPg==")
        no-repeat center;
    }
  }
</style>

<script>
  // JavaScript による追加保護
  document.addEventListener("DOMContentLoaded", function () {
    // 右クリック防止
    document
      .querySelectorAll(".protected-image-container")
      .forEach(function (container) {
        container.addEventListener("contextmenu", function (e) {
          e.preventDefault();
          console.log("Image is protected - Right click disabled");
          return false;
        });

        // ドラッグ防止
        container.addEventListener("dragstart", function (e) {
          e.preventDefault();
          return false;
        });

        // 選択防止
        container.addEventListener("selectstart", function (e) {
          e.preventDefault();
          return false;
        });
      });

    // F12 キー(開発者ツール)の検出
    document.addEventListener("keydown", function (e) {
      if (
        e.keyCode === 123 || // F12
        (e.ctrlKey && e.shiftKey && e.keyCode === 73) || // Ctrl+Shift+I
        (e.ctrlKey && e.shiftKey && e.keyCode === 67) || // Ctrl+Shift+C
        (e.ctrlKey && e.keyCode === 85)
      ) {
        // Ctrl+U
        console.log("Developer tools access detected");
        // 完全に防ぐことはできないが、警告を出すことは可能
      }
    });
  });
</script>

📸 画像準備の推奨事項

1. 事前処理での透かし追加

  • 画像編集ソフトで事前に透かしを追加
  • 目立ちすぎない程度で、削除困難な位置に配置
  • 例:右下角、画像の中央部分に薄く配置

2. 解像度の調整

  • ウェブ表示用:300-500px幅程度
  • 高解像度版は公開しない
  • JPEG圧縮率:70-80%

3. ファイル名の工夫

❌ profile.jpg
❌ fumiyoshi-kobayashi.jpg
✅ prof-fk-2025-q1.jpg
✅ researcher-image-protected.jpg

🚨 制限事項

完全な保護は不可能

  • これらの対策は「抑制効果」を目的としています
  • 技術的に詳しいユーザーは回避可能です
  • しかし、カジュアルな不正利用は大幅に防げます

ユーザビリティとのバランス

  • 保護レベルを上げすぎると使いやすさが損なわれます
  • 正当な利用者にとって使いやすい範囲で設定

🎯 推奨する追加対策

1. 画像の種類による使い分け

- プロフィール写真:最高レベルの保護
- 研究風景写真:中レベルの保護  
- 図表・グラフ:基本レベルの保護

2. 外部サービスの活用

  • Cloudflare の画像保護機能
  • 専用の画像配信サービス(CDN)
  • hotlink protection の設定

3. 法的対策

  • 明確な利用規約の設置
  • 著作権表示の明示
  • 必要に応じて法的手続きの準備

📱 モバイル対応

  • タッチデバイスでの長押し保存防止
  • スクリーンショット検出(一部ブラウザ)
  • レスポンシブデザインでの保護機能維持

🔍 効果測定

確認方法

  1. 右クリック → 無効化されているか
  2. ドラッグ操作 → 画像が動かないか
  3. 開発者ツール → 警告が表示されるか
  4. 印刷プレビュー → 透かしが表示されるか

ログ確認

  • ブラウザのコンソールで保護機能の動作確認
  • 不正アクセス試行の検出

⚖️ 法的注意事項

  • これらの技術的対策は著作権法を補完するものです
  • 法的効力は著作権法に基づきます
  • 重要な画像については専門家にご相談ください

📞 サポート

質問や問題がある場合:

  • GitHub Issues で報告
  • 技術的な改善提案も歓迎

最終更新:2025年6月