fix: resize ICO et comportement sans sélection

- Convertit le mode palette (ICO, GIF) en RGBA avant LANCZOS pour
  éviter l'erreur de resampling sur les sources ICO
- Sans dimension sélectionnée : conserve les dimensions d'origine
- Sans format sélectionné : conserve le format d'origine
- Bouton toujours actif, texte dynamique "Générer la copie / N copies"

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Alpinux 2026-05-06 10:11:17 +02:00
parent 3e8b18b127
commit dd83e6f36e
2 changed files with 43 additions and 11 deletions

View file

@ -686,9 +686,11 @@ def check_resize():
try: try:
sizes = [int(s) for s in raw_sizes if int(s) in RESIZE_SIZES] sizes = [int(s) for s in raw_sizes if int(s) in RESIZE_SIZES]
except (ValueError, TypeError): except (ValueError, TypeError):
return jsonify({"conflicts": []}) sizes = []
formats = [f for f in raw_formats if f in RESIZE_FORMATS] formats = [f for f in raw_formats if f in RESIZE_FORMATS]
src_ext = target.suffix.lstrip(".")
stem = re.sub(r"_\d+x\d+$", "", target.stem) stem = re.sub(r"_\d+x\d+$", "", target.stem)
parent = target.parent parent = target.parent
@ -701,6 +703,19 @@ def check_resize():
except (ValueError, TypeError): except (ValueError, TypeError):
pass pass
# Pas de dimensions sélectionnées → conserver celles d'origine
if not all_dims:
try:
src = Image.open(target)
all_dims = [(src.width, src.height)]
src.close()
except Exception:
return jsonify({"conflicts": []})
# Pas de format sélectionné → conserver le format d'origine
if not formats:
formats = [src_ext]
conflicts = [] conflicts = []
for fmt in formats: for fmt in formats:
for w, h in all_dims: for w, h in all_dims:
@ -764,8 +779,14 @@ def resize_image():
pass pass
all_dims = square_dims + custom_dims all_dims = square_dims + custom_dims
if not all_dims or not formats:
return jsonify({"error": "Aucune dimension ou format valide"}), 400 # Pas de dimensions sélectionnées → conserver celles d'origine
if not all_dims:
all_dims = [(max_w, max_h)]
# Pas de format sélectionné → conserver le format d'origine
if not formats:
formats = [ext.lstrip(".")]
conflict = request.form.get("conflict", "skip") conflict = request.form.get("conflict", "skip")
if conflict not in ("backup", "overwrite", "rename", "skip"): if conflict not in ("backup", "overwrite", "rename", "skip"):
@ -842,6 +863,9 @@ def resize_image():
else: else:
img = Image.open(target) img = Image.open(target)
# LANCZOS ne supporte pas le mode palette (ICO, GIF…)
if img.mode not in ("RGB", "RGBA", "L", "LA", "I", "F"):
img = img.convert("RGBA")
img = img.resize((w, h), Image.LANCZOS) img = img.resize((w, h), Image.LANCZOS)
if fmt == "png": if fmt == "png":
if img.mode not in ("RGBA", "RGB", "L"): if img.mode not in ("RGBA", "RGB", "L"):

View file

@ -143,7 +143,7 @@
{% endif %} {% endif %}
<div class="resize-actions"> <div class="resize-actions">
<button id="resize-btn" class="btn btn-primary" disabled>Générer les copies</button> <button id="resize-btn" class="btn btn-primary">Générer la copie</button>
<span class="resize-hint">Les fichiers sont créés dans le même dossier</span> <span class="resize-hint">Les fichiers sont créés dans le même dossier</span>
</div> </div>
@ -261,19 +261,27 @@
return `${w}x${h}`; return `${w}x${h}`;
} }
function canSubmit() { function countCopies() {
const hasSizes = Array.from(szCbs).some(c => c.checked) || getCustomDim() !== null; const nSizes = Array.from(szCbs).filter(c => c.checked).length
const hasFmts = Array.from(fmtCbs).some(c => c.checked); + (getCustomDim() ? 1 : 0)
return hasSizes && hasFmts; || 1; // 0 sélectionné → dimensions d'origine conservées
const nFmts = Array.from(fmtCbs).filter(c => c.checked).length || 1;
return nSizes * nFmts;
}
function btnLabel() {
const n = countCopies();
return n === 1 ? 'Générer la copie' : `Générer les ${n} copies`;
} }
function updateBtn() { function updateBtn() {
btn.disabled = !canSubmit(); btn.textContent = btnLabel();
conflictPanel.style.display = 'none'; conflictPanel.style.display = 'none';
resizeResolved = false; resizeResolved = false;
} }
[...szCbs, ...fmtCbs].forEach(c => c.addEventListener('change', updateBtn)); [...szCbs, ...fmtCbs].forEach(c => c.addEventListener('change', updateBtn));
updateBtn();
function appendDims(fd) { function appendDims(fd) {
szCbs.forEach(c => { if (c.checked) fd.append('sizes', c.value); }); szCbs.forEach(c => { if (c.checked) fd.append('sizes', c.value); });
@ -318,8 +326,8 @@
result.innerHTML = '<p class="resize-err-title">Erreur réseau.</p>'; result.innerHTML = '<p class="resize-err-title">Erreur réseau.</p>';
} }
result.style.display = 'block'; result.style.display = 'block';
btn.textContent = 'Générer les copies'; btn.textContent = btnLabel();
btn.disabled = !canSubmit(); btn.disabled = false;
resizeResolved = false; resizeResolved = false;
} }