Skip to content

fix(cli): preserve original image bytes when asset!() requests no transform (#5642)#5675

Open
singhlovepreet9 wants to merge 1 commit into
DioxusLabs:mainfrom
singhlovepreet9:fix/asset-png-reencode-5642
Open

fix(cli): preserve original image bytes when asset!() requests no transform (#5642)#5675
singhlovepreet9 wants to merge 1 commit into
DioxusLabs:mainfrom
singhlovepreet9:fix/asset-png-reencode-5642

Conversation

@singhlovepreet9

Copy link
Copy Markdown

Fixes #5642.

Problem

asset!("image.png") with no options re-encodes the image by default, which can significantly increase the size of an already-optimized PNG (the issue reports 193K → 976K).

Root cause

An option-less asset!(...) resolves to ImageAssetOptions::default() = format: ImageFormat::Unknown, size: ImageSize::Automatic. In process_image, format() == Unknown falls into the catch-all (Ok(image), _) => image.save(output_path) arm, which decodes and re-encodes the image with the image crate's default PNG encoder — no optimization, and larger output for already-optimized sources.

Fix

Add an early guard in process_image: when no output format conversion and no manual resize are requested (Unknown + Automatic), copy the source bytes verbatim (the asset is still content-hashed by filename) instead of decoding and re-encoding. This matches the expected behavior in the issue — preserve the original bytes unless image processing is explicitly requested.

Explicit .with_format(...) / .with_size(...) paths are unchanged: those still resize/convert/optimize as before.

if image_options.format() == ImageFormat::Unknown
    && image_options.size() == ImageSize::Automatic
{
    std::fs::copy(source, output_path)?;
    return Ok(());
}

Test

Added opt::image::tests::default_options_preserve_source_bytes: it writes a Best-compressed source PNG carrying a tEXt chunk (which a decode→re-encode drops), runs process_image with default options, and asserts the output is byte-identical to the source — so the test fails if the default path ever re-encodes again.

test opt::image::tests::default_options_preserve_source_bytes ... ok

Ran with cargo +1.93.0 test -p dioxus-cli (repo MSRV 1.93).


Note: @GPNaslund mentioned interest in the issue — happy to defer if they already have a fix in flight; posting this since no PR was up.

@singhlovepreet9 singhlovepreet9 requested a review from a team as a code owner July 11, 2026 15:24
Comment thread packages/cli/src/opt/image.rs Outdated
Comment on lines +12 to +17
// If no image transformation was requested — no explicit output format and no
// manual resize — copy the source bytes verbatim instead of decoding and
// re-encoding. Re-encoding an already-optimized image (e.g. a hand-tuned PNG)
// can significantly *increase* its size, so by default we preserve the original
// bytes and only process the image when the user explicitly asks for a format
// or a size (see https://github.com/DioxusLabs/dioxus/issues/5642).

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

It looks like AI-generated explanatory text that was submitted without sufficient review or cleanup. Six lines of comments narrating such a simple guard in a small function is unreasonable.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Thanks for the feedback! You're completely right—the comment was unnecessarily verbose.I've shortened the comments to a single line, squashed the commits, and updated the PR. Let me know if everything looks good now!

@singhlovepreet9 singhlovepreet9 force-pushed the fix/asset-png-reencode-5642 branch from b077b5a to eb91c04 Compare July 12, 2026 11:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

asset!() re-encodes PNG by default and significantly increases file size

2 participants