Auto HDR Enhanced

Apply an HDR-like effect to images and videos on a webpage with adjustable settings.

  1. // ==UserScript==
  2. // @name Auto HDR Enhanced
  3. // @namespace http://taeparlaytampermonkey.net/
  4. // @version 15.2
  5. // @description Apply an HDR-like effect to images and videos on a webpage with adjustable settings.
  6. // @author tae
  7. // @license MIT
  8. // @match *://*/*
  9. // @grant none
  10. // @run-at document-start
  11. // ==/UserScript==
  12.  
  13. (function () {
  14. 'use strict';
  15.  
  16. // Default settings
  17. const settings = {
  18. hdrEnabled: true,
  19. brightness: 1.0,
  20. contrast: 1.1,
  21. saturation: 0.8,
  22. excludedSites: [],
  23. };
  24.  
  25. // Load settings from local storage
  26. function loadSettings() {
  27. const savedSettings = localStorage.getItem('autoHDRSettings');
  28. if (savedSettings) {
  29. Object.assign(settings, JSON.parse(savedSettings));
  30. }
  31. }
  32.  
  33. // Save settings to local storage
  34. function saveSettings() {
  35. localStorage.setItem('autoHDRSettings', JSON.stringify(settings));
  36. }
  37.  
  38. // Apply HDR-like effect using canvas
  39. function applyHDREffect(img) {
  40. if (!img.complete || img.dataset.hdrApplied) return;
  41.  
  42. const canvas = document.createElement('canvas');
  43. const ctx = canvas.getContext('2d');
  44.  
  45. canvas.width = img.naturalWidth;
  46. canvas.height = img.naturalHeight;
  47.  
  48. ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
  49.  
  50. let imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
  51. const data = imageData.data;
  52.  
  53. // Adjust brightness, contrast, and saturation
  54. for (let i = 0; i < data.length; i += 4) {
  55. let [r, g, b] = [data[i], data[i + 1], data[i + 2]];
  56.  
  57. // Apply brightness and contrast
  58. r = clamp(r * settings.brightness * settings.contrast);
  59. g = clamp(g * settings.brightness * settings.contrast);
  60. b = clamp(b * settings.brightness * settings.contrast);
  61.  
  62. // Apply saturation
  63. [r, g, b] = applySaturation(r, g, b, settings.saturation);
  64.  
  65. [data[i], data[i + 1], data[i + 2]] = [r, g, b];
  66. }
  67.  
  68. ctx.putImageData(imageData, 0, 0);
  69. img.src = canvas.toDataURL();
  70. img.dataset.hdrApplied = true; // Mark as processed
  71. }
  72.  
  73. // Saturation adjustment function
  74. function applySaturation(r, g, b, factor) {
  75. const grayscale = 0.3 * r + 0.59 * g + 0.11 * b;
  76. r += (r - grayscale) * (factor - 1);
  77. g += (g - grayscale) * (factor - 1);
  78. b += (b - grayscale) * (factor - 1);
  79. return [clamp(r), clamp(g), clamp(b)];
  80. }
  81.  
  82. // Clamp values to 0-255
  83. function clamp(value) {
  84. return Math.max(0, Math.min(255, value));
  85. }
  86.  
  87. // Apply CSS filters to videos
  88. function applyHDRToVideos() {
  89. document.querySelectorAll('video:not([data-hdrApplied])').forEach(video => {
  90. video.style.filter = `brightness(${settings.brightness}) contrast(${settings.contrast}) saturate(${settings.saturation})`;
  91. video.dataset.hdrApplied = true;
  92. });
  93. }
  94.  
  95. // Check if the current site is excluded
  96. function isSiteExcluded() {
  97. return settings.excludedSites.some(site => window.location.href.includes(site));
  98. }
  99.  
  100. // Toggle HDR effect on or off
  101. function toggleHDREffect() {
  102. const images = document.querySelectorAll('img');
  103. images.forEach(img => {
  104. if (settings.hdrEnabled) {
  105. applyHDREffect(img);
  106. } else {
  107. if (img.dataset.hdrApplied) {
  108. img.removeAttribute('data-hdrApplied');
  109. img.src = img.src; // Reset image source
  110. }
  111. }
  112. });
  113.  
  114. if (settings.hdrEnabled) {
  115. applyHDRToVideos();
  116. } else {
  117. document.querySelectorAll('video').forEach(video => {
  118. video.style.filter = '';
  119. video.removeAttribute('data-hdrApplied');
  120. });
  121. }
  122. }
  123.  
  124. // Initialize the script
  125. function init() {
  126. loadSettings();
  127.  
  128. if (!isSiteExcluded()) {
  129. const observer = new MutationObserver(() => {
  130. if (settings.hdrEnabled) {
  131. document.querySelectorAll('img:not([data-hdrApplied])').forEach(applyHDREffect);
  132. applyHDRToVideos();
  133. }
  134. });
  135.  
  136. observer.observe(document.body, { childList: true, subtree: true });
  137. window.addEventListener('load', toggleHDREffect);
  138. }
  139. }
  140.  
  141. init();
  142. })();