support SVG upload, fix group www-data sur data/

This commit is contained in:
Cedric Abonnel
2026-05-12 00:51:18 +02:00
parent 6163ce0780
commit b3858af363
5 changed files with 474 additions and 152 deletions
@@ -0,0 +1,162 @@
<svg width="100%" viewBox="0 0 680 400" xmlns="http://www.w3.org/2000/svg" role="img" style="">
<title style="fill:rgb(0, 0, 0);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto">Conversion d'images en ligne de commande sous Linux</title>
<desc style="fill:rgb(0, 0, 0);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto">Une fenêtre de terminal au centre avec une commande ImageMagick, entourée d'images source à gauche en plusieurs formats et d'images converties à droite, illustrant la transformation par ligne de commande.</desc>
<defs>
<linearGradient id="sky" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stop-color="#fab387"/>
<stop offset="100%" stop-color="#f38ba8"/>
</linearGradient>
</defs>
<!-- LEFT SIDE: source images (varied formats, heavier visually) -->
<!-- JPG photo: sunset -->
<g transform="translate(40, 60)" style="fill:rgb(0, 0, 0);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto">
<rect width="110" height="80" rx="4" fill="url(#sky)" stroke="#45475a" stroke-width="0.5" style="stroke:rgb(69, 71, 90);color:rgb(0, 0, 0);stroke-width:0.5px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
<circle cx="78" cy="48" r="14" fill="#f9e2af" opacity="0.9" style="fill:rgb(249, 226, 175);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:0.9;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
<rect x="0" y="62" width="110" height="18" rx="0" fill="#1e3a5f" opacity="0.7" style="fill:rgb(30, 58, 95);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:0.7;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
<rect x="0" y="62" width="110" height="18" fill="none" style="fill:none;stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
<rect x="0" y="80" width="110" height="0" fill="none" style="fill:none;stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
<!-- format badge -->
<rect x="6" y="64" width="34" height="14" rx="2" fill="#1e1e2e" opacity="0.85" style="fill:rgb(30, 30, 46);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:0.85;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
<text x="23" y="74" text-anchor="middle" style="fill:rgb(255, 255, 255);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, system-ui, sans-serif;font-size:11px;font-weight:500;text-anchor:middle;dominant-baseline:auto">JPG</text>
<text x="55" y="98" text-anchor="middle" style="fill:rgb(108, 112, 134);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, system-ui, sans-serif;font-size:11px;font-weight:500;text-anchor:middle;dominant-baseline:auto">4032 × 3024</text>
</g>
<!-- PNG: with transparency checkerboard -->
<g transform="translate(40, 170)" style="fill:rgb(0, 0, 0);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto">
<rect width="110" height="80" rx="4" fill="#ffffff" stroke="#45475a" stroke-width="0.5" style="fill:rgb(255, 255, 255);stroke:rgb(69, 71, 90);color:rgb(0, 0, 0);stroke-width:0.5px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
<g opacity="0.25" style="fill:rgb(0, 0, 0);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:0.25;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto">
<rect x="0" y="0" width="11" height="10" fill="#9ca3af" style="fill:rgb(156, 163, 175);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
<rect x="22" y="0" width="11" height="10" fill="#9ca3af" style="fill:rgb(156, 163, 175);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
<rect x="44" y="0" width="11" height="10" fill="#9ca3af" style="fill:rgb(156, 163, 175);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
<rect x="66" y="0" width="11" height="10" fill="#9ca3af" style="fill:rgb(156, 163, 175);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
<rect x="88" y="0" width="11" height="10" fill="#9ca3af" style="fill:rgb(156, 163, 175);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
<rect x="11" y="10" width="11" height="10" fill="#9ca3af" style="fill:rgb(156, 163, 175);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
<rect x="33" y="10" width="11" height="10" fill="#9ca3af" style="fill:rgb(156, 163, 175);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
<rect x="55" y="10" width="11" height="10" fill="#9ca3af" style="fill:rgb(156, 163, 175);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
<rect x="77" y="10" width="11" height="10" fill="#9ca3af" style="fill:rgb(156, 163, 175);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
<rect x="99" y="10" width="11" height="10" fill="#9ca3af" style="fill:rgb(156, 163, 175);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
<rect x="0" y="20" width="11" height="10" fill="#9ca3af" style="fill:rgb(156, 163, 175);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
<rect x="22" y="20" width="11" height="10" fill="#9ca3af" style="fill:rgb(156, 163, 175);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
<rect x="44" y="20" width="11" height="10" fill="#9ca3af" style="fill:rgb(156, 163, 175);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
<rect x="66" y="20" width="11" height="10" fill="#9ca3af" style="fill:rgb(156, 163, 175);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
<rect x="88" y="20" width="11" height="10" fill="#9ca3af" style="fill:rgb(156, 163, 175);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
</g>
<!-- logo shape -->
<circle cx="55" cy="40" r="20" fill="#89b4fa" style="fill:rgb(137, 180, 250);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
<polygon points="55,28 64,46 46,46" fill="#ffffff" style="fill:rgb(255, 255, 255);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
<rect x="6" y="62" width="34" height="14" rx="2" fill="#1e1e2e" opacity="0.85" style="fill:rgb(30, 30, 46);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:0.85;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
<text x="23" y="72" text-anchor="middle" style="fill:rgb(255, 255, 255);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, system-ui, sans-serif;font-size:11px;font-weight:500;text-anchor:middle;dominant-baseline:auto">PNG</text>
<text x="55" y="98" text-anchor="middle" style="fill:rgb(108, 112, 134);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, system-ui, sans-serif;font-size:11px;font-weight:500;text-anchor:middle;dominant-baseline:auto">1920 × 1080</text>
</g>
<!-- CR2: RAW file representation -->
<g transform="translate(40, 280)" style="fill:rgb(0, 0, 0);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto">
<rect width="110" height="80" rx="4" fill="#11111b" stroke="#45475a" stroke-width="0.5" style="fill:rgb(17, 17, 27);stroke:rgb(69, 71, 90);color:rgb(0, 0, 0);stroke-width:0.5px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
<!-- film strip perforations -->
<rect x="6" y="6" width="6" height="6" fill="#45475a" style="fill:rgb(69, 71, 90);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
<rect x="6" y="20" width="6" height="6" fill="#45475a" style="fill:rgb(69, 71, 90);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
<rect x="6" y="34" width="6" height="6" fill="#45475a" style="fill:rgb(69, 71, 90);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
<rect x="6" y="48" width="6" height="6" fill="#45475a" style="fill:rgb(69, 71, 90);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
<rect x="98" y="6" width="6" height="6" fill="#45475a" style="fill:rgb(69, 71, 90);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
<rect x="98" y="20" width="6" height="6" fill="#45475a" style="fill:rgb(69, 71, 90);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
<rect x="98" y="34" width="6" height="6" fill="#45475a" style="fill:rgb(69, 71, 90);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
<rect x="98" y="48" width="6" height="6" fill="#45475a" style="fill:rgb(69, 71, 90);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
<!-- raw indicator bars -->
<rect x="20" y="14" width="70" height="2" fill="#f38ba8" style="fill:rgb(243, 139, 168);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
<rect x="20" y="22" width="55" height="2" fill="#a6e3a1" style="fill:rgb(166, 227, 161);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
<rect x="20" y="30" width="62" height="2" fill="#89b4fa" style="fill:rgb(137, 180, 250);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
<rect x="20" y="38" width="48" height="2" fill="#f9e2af" style="fill:rgb(249, 226, 175);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
<rect x="20" y="46" width="68" height="2" fill="#cba6f7" style="fill:rgb(203, 166, 247);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
<rect x="6" y="62" width="34" height="14" rx="2" fill="#1e1e2e" opacity="0.95" style="fill:rgb(30, 30, 46);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:0.95;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
<text x="23" y="72" text-anchor="middle" style="fill:rgb(255, 255, 255);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, system-ui, sans-serif;font-size:11px;font-weight:500;text-anchor:middle;dominant-baseline:auto">CR2</text>
<text x="55" y="98" text-anchor="middle" style="fill:rgb(108, 112, 134);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, system-ui, sans-serif;font-size:11px;font-weight:500;text-anchor:middle;dominant-baseline:auto">RAW 24 MB</text>
</g>
<!-- Arrows from sources into the terminal -->
<path d="M 158 100 Q 195 100 215 165" fill="none" stroke="#6c7086" stroke-width="1" stroke-dasharray="3 3" style="fill:none;stroke:rgb(108, 112, 134);color:rgb(0, 0, 0);stroke-width:1px;stroke-dasharray:3px, 3px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
<path d="M 158 210 L 215 200" fill="none" stroke="#6c7086" stroke-width="1" stroke-dasharray="3 3" style="fill:none;stroke:rgb(108, 112, 134);color:rgb(0, 0, 0);stroke-width:1px;stroke-dasharray:3px, 3px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
<path d="M 158 320 Q 195 320 215 245" fill="none" stroke="#6c7086" stroke-width="1" stroke-dasharray="3 3" style="fill:none;stroke:rgb(108, 112, 134);color:rgb(0, 0, 0);stroke-width:1px;stroke-dasharray:3px, 3px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
<!-- CENTER: terminal window -->
<g transform="translate(215, 110)" style="fill:rgb(0, 0, 0);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto">
<!-- window -->
<rect width="250" height="200" rx="8" style="fill:rgb(30, 30, 46);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
<rect width="250" height="26" rx="8" style="fill:rgb(49, 50, 68);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
<rect y="18" width="250" height="8" style="fill:rgb(49, 50, 68);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
<!-- traffic lights -->
<circle cx="14" cy="13" r="5" fill="#f38ba8" style="fill:rgb(243, 139, 168);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
<circle cx="30" cy="13" r="5" fill="#f9e2af" style="fill:rgb(249, 226, 175);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
<circle cx="46" cy="13" r="5" fill="#a6e3a1" style="fill:rgb(166, 227, 161);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
<text x="125" y="17" text-anchor="middle" style="font-size: 11px; fill: #6c7086;;fill:rgb(108, 112, 134);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:ui-monospace, &quot;SF Mono&quot;, Menlo, Consolas, monospace;font-size:11px;font-weight:400;text-anchor:middle;dominant-baseline:auto">cedrix@pve3 — bash</text>
<!-- terminal content -->
<text x="14" y="50" style="fill:rgb(166, 227, 161);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:ui-monospace, &quot;SF Mono&quot;, Menlo, Consolas, monospace;font-size:13px;font-weight:500;text-anchor:start;dominant-baseline:auto">$</text>
<text x="28" y="50" style="fill:rgb(249, 226, 175);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:ui-monospace, &quot;SF Mono&quot;, Menlo, Consolas, monospace;font-size:13px;font-weight:400;text-anchor:start;dominant-baseline:auto">magick</text>
<text x="80" y="50" style="fill:rgb(137, 180, 250);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:ui-monospace, &quot;SF Mono&quot;, Menlo, Consolas, monospace;font-size:13px;font-weight:400;text-anchor:start;dominant-baseline:auto">photo.jpg</text>
<text x="14" y="68" style="fill:rgb(205, 214, 244);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:ui-monospace, &quot;SF Mono&quot;, Menlo, Consolas, monospace;font-size:13px;font-weight:400;text-anchor:start;dominant-baseline:auto"> -resize 1600x1600\&gt;</text>
<text x="14" y="86" style="fill:rgb(205, 214, 244);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:ui-monospace, &quot;SF Mono&quot;, Menlo, Consolas, monospace;font-size:13px;font-weight:400;text-anchor:start;dominant-baseline:auto"> -strip -quality 82</text>
<text x="14" y="104" style="fill:rgb(137, 180, 250);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:ui-monospace, &quot;SF Mono&quot;, Menlo, Consolas, monospace;font-size:13px;font-weight:400;text-anchor:start;dominant-baseline:auto"> web.jpg</text>
<text x="14" y="130" style="fill:rgb(108, 112, 134);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:ui-monospace, &quot;SF Mono&quot;, Menlo, Consolas, monospace;font-size:12px;font-weight:400;text-anchor:start;dominant-baseline:auto"># conversion en cours...</text>
<text x="14" y="148" style="fill:rgb(148, 226, 213);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:ui-monospace, &quot;SF Mono&quot;, Menlo, Consolas, monospace;font-size:12px;font-weight:400;text-anchor:start;dominant-baseline:auto">✓ resize: 1600 × 1067</text>
<text x="14" y="164" style="fill:rgb(148, 226, 213);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:ui-monospace, &quot;SF Mono&quot;, Menlo, Consolas, monospace;font-size:12px;font-weight:400;text-anchor:start;dominant-baseline:auto">✓ exif: stripped</text>
<text x="14" y="180" style="fill:rgb(148, 226, 213);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:ui-monospace, &quot;SF Mono&quot;, Menlo, Consolas, monospace;font-size:12px;font-weight:400;text-anchor:start;dominant-baseline:auto">✓ size: 4.2 MB → 218 KB</text>
<text x="14" y="194" style="fill:rgb(166, 227, 161);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:ui-monospace, &quot;SF Mono&quot;, Menlo, Consolas, monospace;font-size:13px;font-weight:500;text-anchor:start;dominant-baseline:auto">$</text>
<rect x="26" y="184" width="7" height="12" fill="#cdd6f4" style="fill:rgb(205, 214, 244);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:0.332727;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto">
<animate attributeName="opacity" values="1;0;1" dur="1.1s" repeatCount="indefinite" style="fill:rgb(205, 214, 244);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
</rect>
</g>
<!-- Arrows from terminal to outputs -->
<path d="M 470 170 L 525 110" fill="none" stroke="#a6e3a1" stroke-width="1.2" marker-end="url(#arr-green)" style="fill:none;stroke:rgb(166, 227, 161);color:rgb(0, 0, 0);stroke-width:1.2px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
<path d="M 470 210 L 525 210" fill="none" stroke="#a6e3a1" stroke-width="1.2" marker-end="url(#arr-green)" style="fill:none;stroke:rgb(166, 227, 161);color:rgb(0, 0, 0);stroke-width:1.2px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
<path d="M 470 250 L 525 310" fill="none" stroke="#a6e3a1" stroke-width="1.2" marker-end="url(#arr-green)" style="fill:none;stroke:rgb(166, 227, 161);color:rgb(0, 0, 0);stroke-width:1.2px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
<defs>
<marker id="arr-green" viewBox="0 0 10 10" refX="8" refY="5" markerWidth="6" markerHeight="6" orient="auto-start-reverse">
<path d="M2 1L8 5L2 9" fill="none" stroke="#a6e3a1" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
</marker>
</defs>
<!-- RIGHT SIDE: converted outputs (lighter, smaller, optimized) -->
<!-- WebP optimized sunset -->
<g transform="translate(530, 60)" style="fill:rgb(0, 0, 0);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto">
<rect width="110" height="80" rx="4" fill="url(#sky)" stroke="#45475a" stroke-width="0.5" style="stroke:rgb(69, 71, 90);color:rgb(0, 0, 0);stroke-width:0.5px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
<circle cx="78" cy="48" r="14" fill="#f9e2af" opacity="0.9" style="fill:rgb(249, 226, 175);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:0.9;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
<rect x="0" y="62" width="110" height="18" fill="#1e3a5f" opacity="0.7" style="fill:rgb(30, 58, 95);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:0.7;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
<rect x="6" y="64" width="40" height="14" rx="2" fill="#a6e3a1" style="fill:rgb(166, 227, 161);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
<text x="26" y="74" text-anchor="middle" style="fill:#11111b;;fill:rgb(17, 17, 27);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, system-ui, sans-serif;font-size:11px;font-weight:500;text-anchor:middle;dominant-baseline:auto">WEBP</text>
<text x="55" y="98" text-anchor="middle" style="fill:rgb(108, 112, 134);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, system-ui, sans-serif;font-size:11px;font-weight:500;text-anchor:middle;dominant-baseline:auto">1600 × 1200</text>
</g>
<!-- JPG web-ready (smaller) -->
<g transform="translate(530, 170)" style="fill:rgb(0, 0, 0);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto">
<rect width="110" height="80" rx="4" fill="#ffffff" stroke="#45475a" stroke-width="0.5" style="fill:rgb(255, 255, 255);stroke:rgb(69, 71, 90);color:rgb(0, 0, 0);stroke-width:0.5px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
<circle cx="55" cy="40" r="20" fill="#89b4fa" style="fill:rgb(137, 180, 250);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
<polygon points="55,28 64,46 46,46" fill="#ffffff" style="fill:rgb(255, 255, 255);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
<rect x="6" y="62" width="40" height="14" rx="2" fill="#a6e3a1" style="fill:rgb(166, 227, 161);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
<text x="26" y="72" text-anchor="middle" style="fill:#11111b;;fill:rgb(17, 17, 27);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, system-ui, sans-serif;font-size:11px;font-weight:500;text-anchor:middle;dominant-baseline:auto">JPG</text>
<text x="55" y="98" text-anchor="middle" style="fill:rgb(108, 112, 134);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, system-ui, sans-serif;font-size:11px;font-weight:500;text-anchor:middle;dominant-baseline:auto">1600 × 900</text>
</g>
<!-- JPG developed from RAW -->
<g transform="translate(530, 280)" style="fill:rgb(0, 0, 0);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto">
<rect width="110" height="80" rx="4" fill="#cba6f7" stroke="#45475a" stroke-width="0.5" style="fill:rgb(203, 166, 247);stroke:rgb(69, 71, 90);color:rgb(0, 0, 0);stroke-width:0.5px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
<rect x="0" y="0" width="110" height="40" fill="#f38ba8" opacity="0.6" style="fill:rgb(243, 139, 168);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:0.6;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
<rect x="0" y="40" width="110" height="22" fill="#fab387" opacity="0.7" style="fill:rgb(250, 179, 135);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:0.7;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
<rect x="0" y="62" width="110" height="18" fill="#1e3a5f" opacity="0.7" style="fill:rgb(30, 58, 95);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:0.7;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
<rect x="6" y="64" width="40" height="14" rx="2" fill="#a6e3a1" style="fill:rgb(166, 227, 161);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
<text x="26" y="72" text-anchor="middle" style="fill:#11111b;;fill:rgb(17, 17, 27);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, system-ui, sans-serif;font-size:11px;font-weight:500;text-anchor:middle;dominant-baseline:auto">JPG</text>
<text x="55" y="98" text-anchor="middle" style="fill:rgb(108, 112, 134);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, system-ui, sans-serif;font-size:11px;font-weight:500;text-anchor:middle;dominant-baseline:auto">2048 × 1365</text>
</g>
<!-- column labels -->
<text x="95" y="40" text-anchor="middle" style="fill:rgb(108, 112, 134);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, system-ui, sans-serif;font-size:11px;font-weight:500;text-anchor:middle;dominant-baseline:auto">SOURCES</text>
<text x="340" y="100" text-anchor="middle" style="fill:rgb(108, 112, 134);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, system-ui, sans-serif;font-size:11px;font-weight:500;text-anchor:middle;dominant-baseline:auto">TERMINAL</text>
<text x="585" y="40" text-anchor="middle" style="fill:rgb(108, 112, 134);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, system-ui, sans-serif;font-size:11px;font-weight:500;text-anchor:middle;dominant-baseline:auto">SORTIES</text>
</svg>

After

Width:  |  Height:  |  Size: 38 KiB

@@ -4,10 +4,27 @@
"title": "Convertir des images en ligne de commande sous Linux",
"author": "cedric@abonnel.fr",
"published": true,
"published_at": "2025-12-28 14:54:41",
"published_at": "2025-12-28 14:54",
"created_at": "2025-12-28 14:54:41",
"updated_at": "2025-12-28 14:54:41",
"revisions": [],
"cover": "cover.jpg",
"updated_at": "2026-05-12 00:51:02",
"revisions": [
{
"n": 1,
"date": "2026-05-12 00:51:02",
"comment": "",
"title": "Convertir des images en ligne de commande sous Linux"
}
],
"cover": "cover.svg",
"files_meta": {
"illustration_conversion_images_cli_linux.svg": {
"author": "",
"source_url": ""
}
},
"external_links": [],
"seo_title": "",
"seo_description": "",
"og_image": "",
"category": "linux"
}
@@ -0,0 +1,142 @@
La manipulation d'images depuis le terminal est une de ces choses qu'on apprend une fois et qu'on utilise pour toujours. Pas besoin de GIMP, pas besoin d'ouvrir quoi que ce soit : une commande, et c'est réglé.
Voici les outils que j'utilise concrètement, et dans quels cas.
---
## ImageMagick, le plus polyvalent
C'est l'outil de base. Il gère à peu près tous les formats qui existent, et la syntaxe est toujours la même. L'installation est classique :
```bash
sudo apt install imagemagick
```
Convertir un format :
```bash
magick image.jpg image.png
```
Redimensionner sans toucher au ratio, en posant une limite maximale :
```bash
magick image.jpg -resize 1920x1920\> sortie.jpg
```
Le `\>` est important — sans lui, ImageMagick agrandit aussi les petites images. Avec, il ne fait que réduire.
Préparer une image pour le web, en supprimant les métadonnées EXIF et en compressant :
```bash
magick image.jpg -strip -quality 82 image_web.jpg
```
Pour traiter un répertoire entier, `mogrify` fait le même boulot mais **modifie les fichiers en place** — toujours travailler sur une copie ou rediriger vers un autre dossier :
```bash
mogrify -path ./web -resize 1600x1600\> -quality 85 *.jpg
```
---
## libvips, pour les traitements lourds
Quand il y a des centaines de photos ou des images très lourdes (scans, RAW exportés), libvips est nettement plus rapide et utilise beaucoup moins de mémoire qu'ImageMagick. Il charge les images en flux au lieu de tout mettre en RAM.
```bash
sudo apt install libvips-tools
```
```bash
vips resize input.jpg output.jpg 0.5 # diviser la taille par 2
vips copy input.png output.webp # conversion de format
```
La syntaxe est moins intuitive qu'ImageMagick mais les gains sur des gros volumes sont sensibles.
---
## FFmpeg, pas que pour la vidéo
FFmpeg est surtout connu pour la vidéo, mais il convertit les images aussi — utile quand il est déjà installé et qu'on veut éviter une dépendance supplémentaire, ou pour extraire des frames depuis une vidéo :
```bash
ffmpeg -i video.mp4 frame_%04d.jpg
```
Redimensionner en conservant le ratio :
```bash
ffmpeg -i input.jpg -vf scale=1280:-1 output.jpg
```
---
## Les métadonnées EXIF avec exiftool
Les appareils photo embarquent beaucoup d'informations dans les fichiers : coordonnées GPS, modèle d'appareil, réglages. Avant de publier une photo, il vaut mieux vérifier ce qu'elle contient :
```bash
sudo apt install libimage-exiftool-perl
exiftool photo.jpg # lire toutes les métadonnées
exiftool -all= photo.jpg # tout supprimer
exiftool -TagsFromFile src.jpg dst.jpg # copier les métadonnées d'une image à une autre
```
ImageMagick peut aussi supprimer les EXIF avec `-strip`, mais exiftool offre plus de contrôle quand on veut garder certaines balises et supprimer d'autres.
---
## Fichiers RAW
Pour les CR2, NEF, ARW et autres formats propriétaires d'appareils photo, `darktable-cli` est la solution la plus propre :
```bash
darktable-cli input.CR2 output.jpg
```
Il applique les mêmes algorithmes de développement que l'interface graphique de darktable. `dcraw` est une alternative plus ancienne et plus bas niveau :
```bash
dcraw -c photo.CR2 > photo.ppm
```
---
## En pratique
Conversion d'un dossier de PNG en WebP :
```bash
for f in *.png; do
magick "$f" "${f%.png}.webp"
done
```
Pipeline complet pour publication web — redimensionnement, suppression EXIF, compression :
```bash
magick input.jpg -resize 1600x1600\> -strip -quality 80 output.jpg
```
Traitement récursif sur un arbre de dossiers :
```bash
find . -name "*.jpg" -exec magick {} -resize 1200x1200\> {} \;
```
---
## Récap rapide
| Cas d'usage | Outil |
|---|---|
| Usage général | ImageMagick |
| Gros volumes / performance | libvips |
| Déjà dans le pipeline vidéo | FFmpeg |
| Fichiers RAW | darktable-cli |
| Lecture / nettoyage EXIF | exiftool |
Pour 90 % des besoins courants, ImageMagick suffit. libvips vaut le coup d'être appris si on traite régulièrement des lots importants.
+1
View File
@@ -666,6 +666,7 @@ class ArticleManager
'image/webp' => 'webp',
'image/gif' => 'gif',
'image/avif' => 'avif',
'image/svg+xml' => 'svg',
default => null,
};
}