Skip to content

feat(presets): image file size as a range in KB or MB - #791

Merged
KnifeLemon merged 1 commit into
KnifeLemon:mainfrom
SeoJCalive:feature/image-size-range
Oct 30, 2026
Merged

KnifeLemon merged 1 commit into
KnifeLemon:mainfrom
SeoJCalive:feature/image-size-range

Conversation

@SeoJCalive

Copy link
Copy Markdown
Collaborator

What does this change?

A preset's picture size limit becomes a range: a minimum and a maximum, entered in KB or MB. It's for upload forms that ask for something like "60 KB to 500 KB". This follows the plan in the issue. Closes #662

  • KB or MB: the editor shows one "File size" row, [minimum] ~ [maximum] [KB | MB]. One unit is shared by both boxes. A limit under 1 MB opens in KB, so 50 KB no longer shows as "0.1". Switching the unit converts both values without changing them. The preset still stores megabytes (maxSizeMb, and the new minSizeMb), so the settings schema number stays the same.
  • Maximum: works as before: a lower quality, then fewer pixels (not below a 640 px long edge), or the file is refused. A picture limit under 1 MB is now written in KB in the refusal ("62.3 KB > 50 KB"). Videos keep MB.
  • Minimum: a JPG, WebP, AVIF, JXL or JP2 under the minimum is saved again at a higher quality (in steps of 10, then 100). Pixels are never enlarged and nothing is padded. When the maximum is also set, the result never goes over it.
  • When the minimum isn't reached: the file is still saved, and its result gets the notice "Saved, but smaller than the minimum file size". This covers the highest quality still being too small, a format without a quality (PNG, GIF…), the maximum stopping it first, routes that don't fit sizes (animations, multi-page TIFF), and "Compress image" keeping the smaller original. The notice shows in the app and in the CLI (text and --json), next to any other note on the same file.
  • Where it's measured: the final pictures of each file, at the same point as the existing maximum check. With "Save as ZIP" that's the pictures inside the ZIP, not the ZIP. Merge images and multi-page TIFF are measured too. Steps in the middle of a multi-step conversion get no limit, as before. Video frames saved into a folder are left out.
  • Editor checks: a minimum over the maximum can't be saved while the boxes are visible. When the boxes are hidden (a format without a quality, or a Live / Motion Photo), the preset can be saved.

Choices I made

  • Notice as its own flag: a file holds one notice key, and "keep the original" or "replace the original" can overwrite it later. So "under the minimum" is a separate flag on the result (FileResult.UnderMinimumSize) and is added to the other note with a localized {0} Β· {1} string.
  • Minimum bytes are rounded, maximum bytes are cut as before: 1001 KB is 1.001 MB, which becomes 1,000,999.9999… bytes. Cutting it would let a 1-byte-short file pass the minimum, so the minimum rounds. The maximum keeps the current behaviour.
  • CLI text output waits for the final result: a file whose first step only makes a page or PNG for a multi-page TIFF or a merge was printed as "ok" at that step, before its result and notice existed. Such a line is now printed once, at the end, with the result.
  • Small KB maximum on a big photo: the 640 px floor is unchanged. A 4000 Γ— 3000 noisy photo with a 50 KB maximum came out at 31.9 KB, 853 Γ— 640.

Type of change

  • Bug fix
  • New feature or improvement
  • New format or engine
  • Translation
  • Documentation
  • Build, CI or dependencies

How was it tested?

  • dotnet format --verify-no-changes

  • dotnet test

  • Tried it in the app (what you converted or clicked, and on which OS): the preset editor on headless Linux (X11), and real conversions with filee-cli on Linux.

  • Changed-area tests: Core SizeLimitTests, Engines SizeLimitTests, the new App PresetSizeRangeTests, and a CLI test for the notice after a step on the way.

  • Full suites: Core 742 passed and CLI 56 passed, after rebasing on 44408715. Before the rebase, on aad99622: Engines: 1,935 passed, 190 skipped, 8 failed. Two of those (HWPX speed, FBX byte cuts) pass when run on their own. The other six are LibreOffice tests (PackageRepackerTests, SpreadsheetFormatTests ODS/XLS) that fail the same way on the base commit (aad99622) on this machine. App: 1,584 passed, 11 skipped, 4 failed. RenderTests.Engines_page_shows_versions_descriptions_and_download_speed fails on the base commit too. The other three (PresetAvailabilityTests, which open the main window) fail only when SingleMainWindowTests.Rapid_tray_clicks_and_closes_keep_one_main_window runs right before them: that test leaves a main window open on the base commit too (see Follow-up). They pass on their own and together with every other test this PR touches.

  • Build warnings: the same 15 as the base commit.

  • Do the new tests guard the feature: I made 22 mutations, each undoing one part of the change (raising the quality, stopping at the maximum, the measuring point before the ZIP, merge and multi-page TIFF, the notice text, the CLI print timing, the editor's range check and units, minimum byte rounding and so on), and checked that a test fails for every one.

  • The video frame folder test needs FFmpeg, which isn't fetched for Linux here, so it only runs on the Windows CI.

Real conversions (filee-cli, this branch)

Picture Preset Result
1600 Γ— 1200 photo JPG quality 30, 150–500 KB 159.7 KB, same pixels (the base commit gives 64.6 KB)
1600 Γ— 1200 photo WebP quality 30, 60–500 KB 69.0 KB
300 Γ— 200 plain picture JPG, 60–500 KB 49.9 KB at quality 100, with the notice
2000 Γ— 1500 photo JPG, max 50 KB 35.0 KB, same pixels (same as the base commit)
4000 Γ— 3000 noise JPG, max 50 KB 31.9 KB, 853 Γ— 640

For the 300 Γ— 200 picture, filee convert --json lists the file with "notice": "Saved, but smaller than the minimum file size".

A presets.json with minSizeMb also loads in the base commit's build, which ignores the new value and keeps the rest.

Screenshots (UI changes)

The preset editor's picture card. Before, a 50 KB limit showed as 0.1 MB; after, it shows as 50 KB.

Before (50 KB limit) After (same preset)
image image
A 60–500 KB range A minimum over the maximum
image image

Checklist

  • New UI strings are in all src/Filee.App/Assets/i18n/*.json files
  • New third-party code or binaries are listed in THIRD-PARTY-NOTICES.md
  • The PR does one thing (unrelated changes go in a separate PR)

Follow-up (not in this PR)

  • Multi-page TIFF output never had its maximum checked (RunMultiPageTiffAsync skips SizeLimit.Check). This PR adds the minimum notice there but leaves that existing gap as it is.
  • SingleMainWindowTests.Rapid_tray_clicks_and_closes_keep_one_main_window ends with a "tray click while releasing" still pending, so its last close opens a new main window that stays on screen. Whichever test that opens the main window runs next then finds one already open. The test order decides whether this shows up.

A preset's picture size limit gets a minimum next to the maximum, and
both can be entered in KB or MB. The preset keeps megabytes
(ImageOptions.MinSizeMb is new, default 0), so the schema is unchanged
and older versions ignore the minimum.

- The editor shows one "File size" row with a shared KB/MB unit; a limit
  under 1 MB opens in KB, and switching units keeps the values.
- A lossy picture under the minimum is saved again at a higher quality,
  never enlarged or padded, and never over the maximum.
- The final pictures of each file are measured where the maximum is
  checked (inside a ZIP, merged images and multi-page TIFF too). One
  under the minimum is saved with a notice, kept as its own flag next
  to any other note, in the app and the CLI.
- Minimum bytes are rounded; maximum bytes are cut as before.
- An image refusal under 1 MB reads in KB; videos keep MB.
- CLI text prints a file whose first step only fed a merge or a
  multi-page TIFF once, at the end, with its result.
- A minimum over the maximum can't be saved while the boxes show.

Closes KnifeLemon#662
@SeoJCalive SeoJCalive added the macos Run the macOS packages and tests in CI for this pull request label Oct 30, 2026
@github-actions github-actions Bot added the feature New features label Oct 30, 2026

@KnifeLemon KnifeLemon left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, @SeoJCalive! This follows the plan in #662, and CI is green.

  • Settings: stored in MB, with minSizeMb added, so the schema stays the same and old builds ignore the new value.
  • Minimum: a higher quality only. Pixels are never enlarged and nothing is padded, and the maximum always wins.
  • Notice: a separate flag, so "original kept / replaced" can't overwrite it. It shows in the app and the CLI.
  • Where it's measured: the final pictures, before a ZIP; merge images and multi-page TIFF are included.

The 22 mutations, each caught by a test, are a nice touch.

@KnifeLemon
KnifeLemon merged commit 191cdd7 into KnifeLemon:main Oct 30, 2026
11 checks passed
KnifeLemon added a commit to gianabif14/Filee that referenced this pull request Oct 30, 2026
KnifeLemon#791 added eight strings to main after this branch started (minimum file
size, the KB/MB unit and the notice), so id.json was missing them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@SeoJCalive
SeoJCalive deleted the feature/image-size-range branch October 30, 2026 06:37
adnan-bhaldar pushed a commit to adnan-bhaldar/Filee that referenced this pull request Oct 30, 2026
KnifeLemon#791 added eight strings to main after this branch started (minimum file
size, the KB/MB unit and the notice), so id.json was missing them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature New features macos Run the macOS packages and tests in CI for this pull request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature]: Image file size in KB, as a range (minimum and maximum)

2 participants