fix apply

This commit is contained in:
Julian Freeman
2026-01-19 08:58:45 -04:00
parent e1f2c8efc8
commit 713f0885dc
6 changed files with 48 additions and 26 deletions

Binary file not shown.

View File

@@ -170,8 +170,8 @@ async fn export_batch(images: Vec<ExportImageTask>, watermark: WatermarkSettings
let scaled_font = PxScale::from(scale_px);
let (t_width, _t_height) = imageproc::drawing::text_size(scaled_font, &font, &watermark.text);
// 3. Ensure it fits width (Padding 10%)
let max_width = (width as f32 * 0.90) as u32;
// 3. Ensure it fits width (Padding 15%)
let max_width = (width as f32 * 0.85) as u32;
if t_width > max_width {
let ratio = max_width as f32 / t_width as f32;
scale_px *= ratio;
@@ -395,8 +395,8 @@ async fn layout_watermark(path: String, text: String, base_scale: f64) -> Result
let mut font_scale = PxScale::from(scale_px);
let (mut t_width, mut t_height) = imageproc::drawing::text_size(font_scale, &font, &text);
// 3. Auto-Fit Width (Limit to 90% of image width)
let max_width = (width as f32 * 0.90) as u32;
// 3. Auto-Fit Width (Limit to 85% of image width)
let max_width = (width as f32 * 0.85) as u32;
if t_width > max_width {
let ratio = max_width as f32 / t_width as f32;
scale_val *= ratio as f64;
@@ -411,9 +411,15 @@ async fn layout_watermark(path: String, text: String, base_scale: f64) -> Result
let center_x = zca.x * width as f64;
let center_y = zca.y * height as f64;
let half_w = t_width as f64 / 2.0;
let half_h = t_height as f64 / 2.0;
let padding = width as f64 * 0.02;
// Add safety margin to measured text size (Renderer mismatch buffer)
let safe_t_width = t_width as f64 * 1.05;
let safe_t_height = t_height as f64 * 1.05;
let half_w = safe_t_width / 2.0;
let half_h = safe_t_height / 2.0;
// Increase edge padding to 4%
let padding = width as f64 * 0.04;
let min_x = half_w + padding;
let max_x = width as f64 - half_w - padding;

View File

@@ -265,7 +265,7 @@ const stopDrawing = () => {
<!-- Text Watermark Overlay (Only in Add Mode) -->
<div
v-if="store.editMode === 'add' && store.watermarkSettings.text"
class="absolute cursor-move select-none whitespace-nowrap font-sans font-medium"
class="absolute cursor-move select-none whitespace-nowrap font-medium"
:style="{
left: (position.x * 100) + '%',
top: (position.y * 100) + '%',
@@ -274,6 +274,7 @@ const stopDrawing = () => {
color: effectiveColor,
/* Scale based on HEIGHT of the IMAGE */
fontSize: (imageRect.height * effectiveScale) + 'px',
fontFamily: 'Roboto, sans-serif',
height: '0px',
display: 'flex',
alignItems: 'center',

View File

@@ -100,9 +100,9 @@ const applyAll = () => {
/>
</div>
<button
@click="store.recalcCurrentWatermark()"
@click="store.recalcAllWatermarks()"
class="bg-blue-600 hover:bg-blue-500 text-white p-2 rounded flex items-center justify-center transition-colors"
title="Apply & Recalculate Layout"
title="Apply & Recalculate Layout for ALL Images"
>
<RotateCw class="w-4 h-4" />
</button>

View File

@@ -118,23 +118,31 @@ export const useGalleryStore = defineStore("gallery", () => {
}
}
async function recalcCurrentWatermark() {
if (selectedIndex.value < 0 || !selectedImage.value) return;
const img = selectedImage.value;
async function recalcAllWatermarks() {
if (images.value.length === 0) return;
const text = watermarkSettings.value.text;
const baseScale = watermarkSettings.value.scale;
// Process in batches to avoid overwhelming the backend
const batchSize = 5;
for (let i = 0; i < images.value.length; i += batchSize) {
const batch = images.value.slice(i, i + batchSize).map(async (img, batchIdx) => {
const globalIdx = i + batchIdx;
try {
const result = await invoke<{x: number, y: number, scale: number}>("layout_watermark", {
path: img.path,
text: watermarkSettings.value.text,
baseScale: watermarkSettings.value.scale
text: text,
baseScale: baseScale
});
// Apply to current image
setImageManualPosition(selectedIndex.value, result.x, result.y);
setImageSetting(selectedIndex.value, 'scale', result.scale);
setImageManualPosition(globalIdx, result.x, result.y);
setImageSetting(globalIdx, 'scale', result.scale);
} catch (e) {
console.error("Layout failed", e);
console.error(`Layout failed for ${img.name}`, e);
}
});
await Promise.all(batch);
}
}
@@ -192,6 +200,6 @@ export const useGalleryStore = defineStore("gallery", () => {
addMaskStroke,
clearMask,
detectWatermark,
recalcCurrentWatermark
recalcAllWatermarks
};
});

View File

@@ -1 +1,8 @@
@import "tailwindcss";
@font-face {
font-family: 'Roboto';
src: url('/fonts/Roboto-Regular.ttf') format('truetype');
font-weight: normal;
font-style: normal;
}