diff --git a/Auto-Image.js b/Auto-Image.js index 33e794a..7714017 100644 --- a/Auto-Image.js +++ b/Auto-Image.js @@ -499,6 +499,7 @@ function applyTheme() { availableColors: [], activeColorPalette: [], // User-selected colors for conversion paintWhitePixels: true, // Default to ON + paintTransparentPixels: false, // Default to OFF currentCharges: 0, maxCharges: 1, // Default max charges cooldown: CONFIG.COOLDOWN_DEFAULT, @@ -813,7 +814,7 @@ function applyTheme() { const d = cached.data; const a = d[idx + 3]; const alphaThresh = state.customTransparencyThreshold || CONFIG.TRANSPARENCY_THRESHOLD; - if (a < alphaThresh) { + if (!state.paintTransparentPixels && a < alphaThresh) { // Treat as transparent / unavailable // Lightweight debug: show when transparency causes skip (only if verbose enabled) if (window._overlayDebug) console.debug('getTilePixelColor: transparent pixel, skipping', tileKey, x, y, a); @@ -845,7 +846,7 @@ function applyTheme() { const data = ctx.getImageData(x, y, 1, 1).data; const a = data[3]; const alphaThresh = state.customTransparencyThreshold || CONFIG.TRANSPARENCY_THRESHOLD; - if (a < alphaThresh) { + if (!state.paintTransparentPixels && a < alphaThresh) { if (window._overlayDebug) console.debug('getTilePixelColor: transparent pixel (fallback), skipping', tileKey, x, y, a); return null; } @@ -3018,6 +3019,26 @@ function applyTheme() { + +
+ +
+ + + + +
+
+
+
@@ -3761,17 +3786,33 @@ function applyTheme() { }) } - const overlayOpacitySlider = settingsContainer.querySelector("#overlayOpacitySlider"); - const overlayOpacityValue = settingsContainer.querySelector("#overlayOpacityValue"); - const enableBlueMarbleToggle = settingsContainer.querySelector("#enableBlueMarbleToggle"); + const overlayOpacitySlider = settingsContainer.querySelector("#overlayOpacitySlider"); + const overlayOpacityValue = settingsContainer.querySelector("#overlayOpacityValue"); + const enableBlueMarbleToggle = settingsContainer.querySelector("#enableBlueMarbleToggle"); + const settingsPaintWhiteToggle = settingsContainer.querySelector("#settingsPaintWhiteToggle"); + const settingsPaintTransparentToggle = settingsContainer.querySelector("#settingsPaintTransparentToggle"); - if (overlayOpacitySlider && overlayOpacityValue) { - overlayOpacitySlider.addEventListener('input', (e) => { - const opacity = parseFloat(e.target.value); - state.overlayOpacity = opacity; - overlayOpacityValue.textContent = `${Math.round(opacity * 100)}%`; - }); - } + if (overlayOpacitySlider && overlayOpacityValue) { + overlayOpacitySlider.addEventListener('input', (e) => { + const opacity = parseFloat(e.target.value); + state.overlayOpacity = opacity; + overlayOpacityValue.textContent = `${Math.round(opacity * 100)}%`; + }); + } + + if (settingsPaintWhiteToggle) { + settingsPaintWhiteToggle.addEventListener('change', (e) => { + state.paintWhitePixels = e.target.checked; + saveBotSettings(); + }); + } + + if (settingsPaintTransparentToggle) { + settingsPaintTransparentToggle.addEventListener('change', (e) => { + state.paintTransparentPixels = e.target.checked; + saveBotSettings(); + }); + } // Speed slider event listener const speedSlider = settingsContainer.querySelector("#speedSlider"); @@ -3822,6 +3863,7 @@ function applyTheme() { const heightValue = resizeContainer.querySelector("#heightValue") const keepAspect = resizeContainer.querySelector("#keepAspect") const paintWhiteToggle = resizeContainer.querySelector("#paintWhiteToggle"); + const paintTransparentToggle = resizeContainer.querySelector("#paintTransparentToggle"); const zoomSlider = resizeContainer.querySelector("#zoomSlider"); const zoomValue = resizeContainer.querySelector('#zoomValue'); const zoomInBtn = resizeContainer.querySelector('#zoomInBtn'); @@ -4133,6 +4175,7 @@ function applyTheme() { zoomSlider.value = 1; if (zoomValue) zoomValue.textContent = '100%'; paintWhiteToggle.checked = state.paintWhitePixels; + paintTransparentToggle.checked = state.paintTransparentPixels; let _previewTimer = null; let _previewJobId = 0; @@ -4236,7 +4279,7 @@ function applyTheme() { const idx = y * w + x; const i4 = idx * 4; const r = data[i4], g = data[i4 + 1], b = data[i4 + 2], a = data[i4 + 3]; - const isEligible = a >= tThresh && (state.paintWhitePixels || !Utils.isWhitePixel(r, g, b)); + const isEligible = (state.paintTransparentPixels || a >= tThresh) && (state.paintWhitePixels || !Utils.isWhitePixel(r, g, b)); eligible[idx] = isEligible ? 1 : 0; work[idx * 3] = r; work[idx * 3 + 1] = g; @@ -4288,7 +4331,7 @@ function applyTheme() { } else { for (let i = 0; i < data.length; i += 4) { const r = data[i], g = data[i + 1], b = data[i + 2], a = data[i + 3]; - if (a < tThresh || (!state.paintWhitePixels && Utils.isWhitePixel(r, g, b))) { + if ((!state.paintTransparentPixels && a < tThresh) || (!state.paintWhitePixels && Utils.isWhitePixel(r, g, b))) { data[i + 3] = 0; continue; } @@ -4335,10 +4378,17 @@ function applyTheme() { if (!isNaN(fit) && isFinite(fit)) applyZoom(fit); }; - paintWhiteToggle.onchange = (e) => { - state.paintWhitePixels = e.target.checked; - _updateResizePreview(); - }; + paintWhiteToggle.onchange = (e) => { + state.paintWhitePixels = e.target.checked; + _updateResizePreview(); + saveBotSettings(); + }; + + paintTransparentToggle.onchange = (e) => { + state.paintTransparentPixels = e.target.checked; + _updateResizePreview(); + saveBotSettings(); + }; let panX = 0, panY = 0; const clampPan = () => { @@ -4772,7 +4822,7 @@ function applyTheme() { const i4 = idx * 4; const r = data[i4], g = data[i4 + 1], b = data[i4 + 2], a = data[i4 + 3]; const masked = mask && mask[idx]; - const isEligible = !masked && a >= tThresh2 && (state.paintWhitePixels || !Utils.isWhitePixel(r, g, b)); + const isEligible = !masked && (state.paintTransparentPixels || a >= tThresh2) && (state.paintWhitePixels || !Utils.isWhitePixel(r, g, b)); eligible[idx] = isEligible ? 1 : 0; work[idx * 3] = r; work[idx * 3 + 1] = g; @@ -4829,7 +4879,7 @@ function applyTheme() { for (let i = 0; i < data.length; i += 4) { const r = data[i], g = data[i + 1], b = data[i + 2], a = data[i + 3]; const masked = mask && mask[(i>>2)]; - const isTransparent = a < tThresh2 || masked; + const isTransparent = (!state.paintTransparentPixels && a < tThresh2) || masked; const isWhiteAndSkipped = !state.paintWhitePixels && Utils.isWhitePixel(r, g, b); if (isTransparent || isWhiteAndSkipped) { data[i + 3] = 0; // overlay transparency @@ -4963,7 +5013,7 @@ function applyTheme() { let totalValidPixels = 0; for (let i = 0; i < pixels.length; i += 4) { - const isTransparent = pixels[i + 3] < (state.customTransparencyThreshold || CONFIG.TRANSPARENCY_THRESHOLD); + const isTransparent = !state.paintTransparentPixels && pixels[i + 3] < (state.customTransparencyThreshold || CONFIG.TRANSPARENCY_THRESHOLD); const isWhiteAndSkipped = !state.paintWhitePixels && Utils.isWhitePixel(pixels[i], pixels[i + 1], pixels[i + 2]); if (!isTransparent && !isWhiteAndSkipped) { totalValidPixels++; @@ -5208,7 +5258,7 @@ function applyTheme() { const isEligibleAt = (x, y) => { const idx = (y * width + x) * 4; const r = pixels[idx], g = pixels[idx + 1], b = pixels[idx + 2], a = pixels[idx + 3]; - if (a < tThresh2) return false; + if (!state.paintTransparentPixels && a < tThresh2) return false; if (!state.paintWhitePixels && Utils.isWhitePixel(r, g, b)) return false; return true; }; @@ -5256,8 +5306,8 @@ function applyTheme() { const alpha = pixels[idx + 3] const tThresh2 = state.customTransparencyThreshold || CONFIG.TRANSPARENCY_THRESHOLD; - if (alpha < tThresh2 || (!state.paintWhitePixels && Utils.isWhitePixel(r, g, b))) { - if (alpha < tThresh2) { + if ((!state.paintTransparentPixels && alpha < tThresh2) || (!state.paintWhitePixels && Utils.isWhitePixel(r, g, b))) { + if (!state.paintTransparentPixels && alpha < tThresh2) { skippedPixels.transparent++; } else { skippedPixels.white++; @@ -5654,6 +5704,7 @@ function applyTheme() { customTransparencyThreshold: state.customTransparencyThreshold, customWhiteThreshold: state.customWhiteThreshold, paintWhitePixels: state.paintWhitePixels, + paintTransparentPixels: state.paintTransparentPixels, resizeSettings: state.resizeSettings, originalImage: state.originalImage, // Save ignore mask (as base64) with its dimensions @@ -5699,6 +5750,7 @@ function applyTheme() { state.customTransparencyThreshold = settings.customTransparencyThreshold ?? CONFIG.TRANSPARENCY_THRESHOLD; state.customWhiteThreshold = settings.customWhiteThreshold ?? CONFIG.WHITE_THRESHOLD; state.paintWhitePixels = settings.paintWhitePixels ?? true; + state.paintTransparentPixels = settings.paintTransparentPixels ?? false; state.resizeSettings = settings.resizeSettings ?? null; state.originalImage = settings.originalImage ?? null; // Notifications diff --git a/auto-image-styles.css b/auto-image-styles.css index 2a44553..4d70205 100644 --- a/auto-image-styles.css +++ b/auto-image-styles.css @@ -1117,6 +1117,10 @@ font-size: 16px; } +.wplace-icon-paint { + font-size: 16px; +} + /* Section wrapper styling */ .wplace-settings-section-wrapper { padding: 18px; @@ -1814,6 +1818,7 @@ .wplace-icon-bell { font-size: 16px; } .wplace-icon-palette { font-size: 16px; } .wplace-icon-globe { font-size: 16px; } +.wplace-icon-paint { font-size: 16px; } .wplace-icon-eye { font-size: 16px; } /* Overlay Settings Controls */ diff --git a/lang/en.json b/lang/en.json index b8173f2..cb50b95 100644 --- a/lang/en.json +++ b/lang/en.json @@ -136,5 +136,8 @@ "expandMode": "Expand Mode", "minimize": "Minimize", "restore": "Restore", - "hideStats": "Hide Stats" + "hideStats": "Hide Stats", + "paintOptions": "Paint Options", + "paintWhitePixels": "Paint White Pixels", + "paintTransparentPixels": "Paint Transparent Pixels" } \ No newline at end of file diff --git a/lang/fr.json b/lang/fr.json index 841722e..8d0d2f5 100644 --- a/lang/fr.json +++ b/lang/fr.json @@ -137,5 +137,8 @@ "expandMode": "Mode Étendu", "minimize": "Réduire", "restore": "Restaurer", - "hideStats": "Masquer les Stats" + "hideStats": "Masquer les Stats", + "paintOptions": "Options de peinture", + "paintWhitePixels": "Peindre les pixels blancs", + "paintTransparentPixels": "Peindre les pixels transparents" } diff --git a/lang/id.json b/lang/id.json index 69a1114..9cad6e2 100644 --- a/lang/id.json +++ b/lang/id.json @@ -137,5 +137,8 @@ "expandMode": "Mode Perluas", "minimize": "Minimalkan", "restore": "Pulihkan", - "hideStats": "Sembunyikan Statistik" + "hideStats": "Sembunyikan Statistik", + "paintOptions": "Opsi Pewarnaan", + "paintWhitePixels": "Warnai piksel putih", + "paintTransparentPixels": "Warnai piksel transparan" } diff --git a/lang/ja.json b/lang/ja.json index 3f3de41..d2fc973 100644 --- a/lang/ja.json +++ b/lang/ja.json @@ -137,5 +137,8 @@ "expandMode": "展開モード", "minimize": "最小化", "restore": "復元", - "hideStats": "統計を非表示" + "hideStats": "統計を非表示", + "paintOptions": "描画オプション", + "paintWhitePixels": "白いピクセルを描画", + "paintTransparentPixels": "透明ピクセルを描画" } diff --git a/lang/ko.json b/lang/ko.json index 565870a..570183b 100644 --- a/lang/ko.json +++ b/lang/ko.json @@ -137,5 +137,8 @@ "expandMode": "확장 모드", "minimize": "최소화", "restore": "복원", - "hideStats": "통계 숨김" + "hideStats": "통계 숨김", + "paintOptions": "페인트 옵션", + "paintWhitePixels": "흰색 픽셀 칠하기", + "paintTransparentPixels": "투명 픽셀 칠하기" } diff --git a/lang/pt.json b/lang/pt.json index e72e730..ebbc4f6 100644 --- a/lang/pt.json +++ b/lang/pt.json @@ -136,5 +136,8 @@ "expandMode": "Modo Expandir", "minimize": "Minimizar", "restore": "Restaurar", - "hideStats": "Ocultar Estatísticas" + "hideStats": "Ocultar Estatísticas", + "paintOptions": "Opções de pintura", + "paintWhitePixels": "Pintar pixels brancos", + "paintTransparentPixels": "Pintar pixels transparentes" } \ No newline at end of file diff --git a/lang/ru.json b/lang/ru.json index 096d00b..1bb8b16 100644 --- a/lang/ru.json +++ b/lang/ru.json @@ -136,5 +136,8 @@ "expandMode": "Режим расширения", "minimize": "Свернуть", "restore": "Восстановить", - "hideStats": "Скрыть статистику" + "hideStats": "Скрыть статистику", + "paintOptions": "Параметры рисования", + "paintWhitePixels": "Рисовать белые пиксели", + "paintTransparentPixels": "Рисовать прозрачные пиксели" } \ No newline at end of file diff --git a/lang/tr.json b/lang/tr.json index 097f53e..3a12640 100644 --- a/lang/tr.json +++ b/lang/tr.json @@ -137,5 +137,8 @@ "expandMode": "Genişletme Modu", "minimize": "Küçült", "restore": "Geri Yükle", - "hideStats": "İstatistikleri Gizle" + "hideStats": "İstatistikleri Gizle", + "paintOptions": "Boya Seçenekleri", + "paintWhitePixels": "Beyaz pikselleri boya", + "paintTransparentPixels": "Şeffaf pikselleri boya" } diff --git a/lang/uk.json b/lang/uk.json index 2b5795a..a311474 100644 --- a/lang/uk.json +++ b/lang/uk.json @@ -137,5 +137,8 @@ "expandMode": "Режим розширення", "minimize": "Мінімізувати", "restore": "Відновити", - "hideStats": "Приховати статистику" + "hideStats": "Приховати статистику", + "paintOptions": "Параметри малювання", + "paintWhitePixels": "Малювати білі пікселі", + "paintTransparentPixels": "Малювати прозорі пікселі" } diff --git a/lang/vi.json b/lang/vi.json index 46b9d9e..ea79866 100644 --- a/lang/vi.json +++ b/lang/vi.json @@ -137,5 +137,8 @@ "expandMode": "Chế độ mở rộng", "minimize": "Thu nhỏ", "restore": "Khôi phục", - "hideStats": "Ẩn thống kê" + "hideStats": "Ẩn thống kê", + "paintOptions": "Tùy chọn vẽ", + "paintWhitePixels": "Vẽ điểm ảnh trắng", + "paintTransparentPixels": "Vẽ điểm ảnh trong suốt" } diff --git a/lang/zh-CN.json b/lang/zh-CN.json index 9075743..9058c37 100644 --- a/lang/zh-CN.json +++ b/lang/zh-CN.json @@ -137,5 +137,8 @@ "expandMode": "展开模式", "minimize": "最小化", "restore": "恢复", - "hideStats": "隐藏统计" + "hideStats": "隐藏统计", + "paintOptions": "绘图选项", + "paintWhitePixels": "绘制白色像素", + "paintTransparentPixels": "绘制透明像素" } diff --git a/lang/zh-TW.json b/lang/zh-TW.json index 4173338..384886e 100644 --- a/lang/zh-TW.json +++ b/lang/zh-TW.json @@ -137,5 +137,8 @@ "expandMode": "展開模式", "minimize": "最小化", "restore": "恢復", - "hideStats": "隱藏統計" + "hideStats": "隱藏統計", + "paintOptions": "繪圖選項", + "paintWhitePixels": "繪製白色像素", + "paintTransparentPixels": "繪製透明像素" } diff --git a/themes/classic-light.css b/themes/classic-light.css index 8628ab5..2322dcc 100644 --- a/themes/classic-light.css +++ b/themes/classic-light.css @@ -425,6 +425,7 @@ .wplace-theme--classic-light .wplace-icon-bell { color: #ffc107; } .wplace-theme--classic-light .wplace-icon-palette { color: #f093fb; } .wplace-theme--classic-light .wplace-icon-globe { color: #ffeaa7; } +.wplace-theme--classic-light .wplace-icon-paint { color: #4facfe; } .wplace-theme--classic-light .wplace-icon-eye { color: #6f42c1; } /* Clean light theme animations */ diff --git a/themes/classic.css b/themes/classic.css index 50d902f..910f449 100644 --- a/themes/classic.css +++ b/themes/classic.css @@ -480,13 +480,18 @@ } :root .wplace-icon-globe, -.wplace-theme--classic .wplace-icon-globe { - color: #ffeaa7; +.wplace-theme--classic .wplace-icon-globe { + color: #ffeaa7; +} + +:root .wplace-icon-paint, +.wplace-theme--classic .wplace-icon-paint { + color: #4facfe; } :root .wplace-icon-eye, -.wplace-theme--classic .wplace-icon-eye { - color: var(--wplace-highlight); +.wplace-theme--classic .wplace-icon-eye { + color: var(--wplace-highlight); } /* Form controls and sliders for classic theme */