Repository navigation
feat: choose the compression level, with the estimated size (#1353) - #1386
Conversation
) Preset.AskCompression, off by default: no settings migration. On for the four "Compress" presets in a new install only, as Split PDF's pages (KnifeLemon#981). AskedCompression decides which drops ask (not a merge, group or tool) and what each file gets: the quality of a picture in a lossy format, the quality of a video, the bitrate of sound, the level of a PDF. A PNG or a document converts as the preset says. Apply gives the preset as it runs, and the arithmetic the window's estimate uses (bitrate x length, the size limit and "only keep if smaller" as caps). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BPxh5siZR4PzK81twSxnAb
…emon#1353) CompressionEstimator reads the dropped files once and estimates their total at each setting the window offers: - video and audio: the bitrate the encoder is given (for a constant quality video, the table Filee already uses to give a graphics chip the same quality) times the length ffprobe reads; a copied video keeps its size; - pictures: a full-resolution tile from the middle is really encoded at the quality and scaled up to the whole picture; - PDF: the built-in compressor really runs, into a stream that only counts bytes, once per level. The preset's size limit and "only keep if smaller" cap the result. Only the first files of each kind are read; the others count at their ratio. Tests hold the estimate against real conversions. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BPxh5siZR4PzK81twSxnAb
…eLemon#1353) Files dropped on a preset that asks for its compression open a small "Choose the compression" window first, like "Choose pages" (KnifeLemon#981): the preset editor's own setting for each kind of file dropped (picture quality, video quality, audio bitrate, PDF level) and about what the files come to ("About 30.0 MB (70% smaller)"), estimated again a moment after each change and said to be an estimate. Enter compresses at that setting, which the preset keeps for the next time; Esc starts nothing. Files with nothing to choose (a PNG) convert without the window. - Preset editor: "Ask every time" under the setting it asks for, with a hint; not for a merge. - Strings in all 22 languages. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BPxh5siZR4PzK81twSxnAb
…nifeLemon#1353) The window disposes the estimator when it closes; Dispose now waits for an estimate under way instead of pulling its pictures and lock from under it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BPxh5siZR4PzK81twSxnAb
KnifeLemon
left a comment
There was a problem hiding this comment.
Thank you, this is a careful take on #1353. It reuses the editor's own settings, follows "Choose pages" closely, and the estimate is checked against real conversions. The screenshots helped a lot.
One thing to fix before we merge:
-
Files that can't be estimated drop out of the total. In
CompressionEstimator.Estimate, a sampled file whoseEstimateOnereturns null is skipped. It isn't added tosourceKnown, and it isn't scaled at the ratio like the unsampled files, so its bytes disappear from the total. The window's "size now" still counts them, so the estimate reads too small and "% smaller" too large.
The common case is HEIC.LossyImageTargetsincludesheic, but ImageMagick can't encode HEIC here (Filee writes it through FFmpeg), soImageBytesthrows onToByteArray(MagickFormat.Heic)and returns null. A JPG + HEIC drop from a phone leaves the HEIC out of the estimate, and HEIC alone shows "can't estimate". A video file without a video stream on "Compress video" behaves the same way.
Could you count such files at their kind's ratio, as the unsampled ones are? For HEIC, either estimate it another way or leave it out ofKindOfuntil it can be estimated. A test with one file that can't be estimated next to one that can would pin it down. -
Keep the choice to this run. Right now a level picked in the window is saved into the preset, and watch folders and the command line use that preset too, so a one-off choice on the donut quietly changes them. Please apply it to this conversion only, the way Choose pages does. If you'd like a way to keep it, a Remember for this preset checkbox (off by default) is fine.
We'll start CI: first-time PRs need a maintainer to approve the workflow run.
…KnifeLemon#1353) Review of KnifeLemon#1386: a read file whose estimate failed dropped out of the total while the window's "size now" still counted it, so the estimate read too small and "% smaller" too large. Such files now count at their kind's ratio, as the files that weren't read do; a kind with no file estimated still gives no estimate. HEIC leaves the window: Filee writes it through FFmpeg and ImageMagick can't encode the tile the estimate rests on. A HEIC file converts with the preset's own quality, as a PNG does, and AskedCompression.Runs keeps a level chosen for the JPGs from reaching the files without one. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BPxh5siZR4PzK81twSxnAb
…1353) Review of KnifeLemon#1386: the level picked in the window was saved into the preset, which watch folders and the command line also use, so a one-off choice on the donut quietly changed them. It now applies to this conversion only, as "Choose pages" does; a "Remember for this preset" checkbox, off by default, keeps it. Files without a level convert in a run of their own with the preset as it is. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BPxh5siZR4PzK81twSxnAb
|
Thanks for the review! Both points are addressed:
|
Resolves the conflict in PresetEditorView.axaml: the iPhone ringtone hint (KnifeLemon#1349) and the compression "Ask every time" checkbox both go under the media options. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BPxh5siZR4PzK81twSxnAb
KnifeLemon
left a comment
There was a problem hiding this comment.
Thanks for the quick turnaround, both points are done well: the files that can't be estimated now count at their kind's ratio, and the choice stays with this conversion unless "Remember for this preset" is ticked.
Two small things came with splitting the drop into two runs:
- "Ask every time" asks twice. When the preset asks where to save, a mixed drop (say JPGs and a PNG on "Compress image") now calls
AskThenConvertAsynconce per run, so the save dialog opens twice for one drop and the two parts can end up in different folders. Could you ask for the location once and use it for both runs (or keep them in one job with the setting per file)? Without "Ask every time", two jobs are fine. - The checkbox still shows for HEIC.
ShowAskCompressionImageuses the editor'sLossyTargets, which still hasheic, butAskedCompression.KindOfno longer does. So a custom "→ HEIC" preset offers "Ask every time" for the compression, saves it, and then never opens the window. Could you show the checkbox only for "same as source" and the targets inAskedCompression.LossyImageTargets? The quality slider can stay for HEIC.
Main has moved on since: #1370 and #1389 touched Preset.cs and PresetEditorViewModel.cs, so the branch conflicts now. You don't need to resolve that. We'll merge main when we merge. If you'd rather do it with these fixes, that's fine too.
…et (KnifeLemon#1353) Review of KnifeLemon#1386: - "Ask every time" asked twice: with a mixed drop (JPGs and a PNG on "Compress image") each run opened its own save dialog, and the two parts could land in different folders. The place is now asked once for the whole drop and goes to every run (AskedCompression.Runs takes it). - The editor offered "Ask every time" for a HEIC target, which never opens the window. The checkbox now shows only for "same as source" and the targets in AskedCompression.LossyImageTargets; HEIC keeps its slider. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BPxh5siZR4PzK81twSxnAb
Resolves the conflicts with KnifeLemon#1370 and KnifeLemon#1389 in Preset.cs and PresetEditorViewModel.cs: the slice icon, short name and label fields sit next to AskCompression (both cloned), and the source bookmarks and the compression checkboxes are both notified. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BPxh5siZR4PzK81twSxnAb
|
Thanks! Both are fixed:
|
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
KnifeLemon
left a comment
There was a problem hiding this comment.
Thanks, @Ugoyo! Both points from the last round are in:
- a mixed drop now asks for the save location once, and every run uses it
- "Ask every time" only shows for targets the window can estimate, so HEIC keeps its slider without it
We pushed one small commit on top that changes the new Korean strings to the polite 해요체 used across the app. Nothing else changed.
What does this change?
Closes #1353. The four "Compress" tools can ask for the level each time. Dropping files on one opens a small "Choose the compression" window, built like "Choose pages" (#981). It shows the preset editor's own setting for each kind of file dropped (picture quality slider, video quality, audio bitrate, PDF level) and the size the files will roughly come to: "About 30.0 MB (70% smaller)". The window says it is an estimate. Enter compresses at that setting, which the preset keeps for next time. Esc starts nothing.
Preset.AskCompressionis off by default, so there is no settings migration (same approach asAskPageRange). It is on forcompress-image,compress-video,compress-audioandcompress-pdfin a new install only. Existing users turn it on in the preset editor: "Ask every time" sits under the setting it asks for, with a hint, and is not offered for merges. Watch folders and the CLI use the preset's own values.MediaQuality,PdfCompression,AudioBitrateKbps. The imageMaxSizeMband videoMaxSizeMb/MaxSizePercentlimits cap the estimate, as they cap the result. No new compression settings.How the size is estimated (
Filee.Engines/CompressionEstimator.cs):HardwareVideo.BitrateKbps) + audio, × length. A video that would be copied keeps its size.PdfCompressorreally runs into a byte-counting stream, once per level"Only keep if smaller" and the size limits cap the estimate. Only the first files of each kind are read (12 pictures, 4 PDFs, 40 media files); the rest count at the same ratio.
Type of change
How was it tested?
dotnet format Filee.slnx --verify-no-changes --severity warn, anddotnet build Filee.slnx -c Release(0 errors)dotnet test, in a Linux container:AskedCompressionTests(Core),CompressionEstimatorTests(Engines),AskCompressionTests(App). They hold the estimate against real conversions: picture, PDF, audio and video. The audio and video tests ran with the distro's FFmpeg. The App test drives the real donut → window → Enter/Esc → compressed file.FolderCopyTests.Original_that_cannot_be_deleted…, which also fails onmainhere (the container runs as root).mainin this container (glyph tests for CJK, emoji and Bengali, the Engines page). The eighth,RenderTests.Reset_to_default_sits_beside_delete… (ar), passes when run on its own: it is flaky in the full run, likeAskPagesTests (ja, dark)onmain.mainit already has 18 failures here, because Pandoc and LibreOffice are missing.Screenshots (UI changes)
The window, from the headless render tests. The sizes come from a fixed fake estimate (100 MB → 30 MB) used only for the render; the full Windows path is how the test feeds a file name on Linux.
"Ask every time" in the preset editor, under the setting it asks for:
Checklist
src/Filee.App/Assets/i18n/*.jsonfilesTHIRD-PARTY-NOTICES.md(none added)