Skip to content

Support browser image transformations#7845

Open
evan6seven wants to merge 6 commits into
decaporg:mainfrom
evan6seven:image-conversions
Open

Support browser image transformations#7845
evan6seven wants to merge 6 commits into
decaporg:mainfrom
evan6seven:image-conversions

Conversation

@evan6seven

@evan6seven evan6seven commented Jun 6, 2026

Copy link
Copy Markdown

From Issue #7107

Summary

Adds browser-side media processing for image uploads. Projects can process an uploaded image once before it is persisted by the normal media upload flow, with support for resizing, aspect-ratio cropping, metadata stripping through re-encoding, and optional JPEG/WebP conversion.

Configuration

media_processing:
  enabled: true
  format:
    enabled: true
    default: webp # jpeg | webp
  quality: 80 # 1-100
  strip_metadata: true
  width: null
  height: null
  aspect_ratio: 16_9

Notes on the config:

  • media_processing can be set globally or on an individual image/file field; field config overrides the global config.
  • format.enabled: true converts the upload to jpeg or webp.
  • format.enabled: false keeps the uploaded image's original supported type (jpeg, png, or webp) while still allowing resize/crop/re-encode processing.
  • quality is a plain number from 1 to 100; there is no auto quality mode.
  • aspect_ratio accepts values like 16_9 16:9 16x9.
  • SVG uploads are not processed.

Conversion methods

  • Images are decoded and resized/cropped in the browser with Canvas.
  • JPEG output uses Canvas toBlob with the configured quality.
  • WebP output uses @jsquash/webp, so WebP compression works in browsers that cannot encode WebP through Canvas, including Safari.
  • PNG is supported only as an original pass-through type when format conversion is disabled; it is not a configurable conversion target.
  • WebAssembly assets from @jsquash/webp are emitted through the webpack WASM asset rule.

What changed

  • Adds the media_processing config schema and TypeScript declarations.
  • Reads media processing config from root config or field-level overrides.
  • Runs a single processed output through the existing media persistence flow.
  • Uses processed filenames for replacement checks and media insertion.
  • Preserves the original filename when format conversion is disabled.
  • Keeps draft media selection and public path handling compatible with processed uploads.
@evan6seven evan6seven requested a review from a team as a code owner June 6, 2026 22:17
@evan6seven evan6seven marked this pull request as draft June 6, 2026 22:19
@evan6seven evan6seven force-pushed the image-conversions branch from f1a29e3 to 366ec3e Compare June 6, 2026 22:20
@evan6seven evan6seven changed the title Support browser image transformations Jun 6, 2026
@evan6seven evan6seven changed the title Support browser image transformations #2808 Jun 6, 2026
@evan6seven evan6seven marked this pull request as ready for review June 6, 2026 22:29
@martinjagodic

Copy link
Copy Markdown
Member

@evan6seven this would be a great feature in Decap CMS, but before we merge it, we need to agree on what it would look like. Did you see issue #7107? There was a lot of debate around how to do it. I think it addresses a similar question, but in much more detail.

You added the Photon dependency, which could be a good fit, but I have some concerns. Most notably, it's maintained by a single person. The history is not in favor of the longevity of such libraries, so we have to be really cautious before we use it.

@evan6seven

Copy link
Copy Markdown
Author

Thanks, I had not seen that issue discussion. I will read it and incorporate decisions from there.

@evan6seven evan6seven marked this pull request as draft June 16, 2026 16:18

@yanthomasdev yanthomasdev left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Amazing work @evan6seven, I see your PR is a draft so I'm leaving just a few initial comments/suggestions for you to consider

Comment thread packages/decap-cms-core/src/lib/imageTransformations.ts Outdated
Comment thread packages/decap-cms-core/src/lib/imageTransformations.ts Outdated
Comment thread packages/decap-cms-core/src/actions/mediaLibrary.ts Outdated
@evan6seven

evan6seven commented Jun 17, 2026

Copy link
Copy Markdown
Author

Having looked at the original issue thread what I took away was:

  • Use minimal libraries
  • Support a few cropping and resizing operations

I'm minimizing libraries by using Canvas for jpeg and png images.
In terms of libraries, I'm using @jSquash/webp. This seems necessary as webp not supported in Safari's Canvas encoding. Do we want to add @jSquash/avif?

@yanthomasdev thanks for the feedback, I've updated based on it.

@evan6seven evan6seven marked this pull request as ready for review June 17, 2026 22:51
@yanthomasdev

Copy link
Copy Markdown
Contributor

Great work @evan6seven, I believe this should be good to go. I added the missing strip_metadata config and handling from your original description, let me know if that looks alright.

@evan6seven

Copy link
Copy Markdown
Author

Great work @evan6seven, I believe this should be good to go. I added the missing strip_metadata config and handling from your original description, let me know if that looks alright.

Yeah, looks good

@evan6seven

evan6seven commented Jun 19, 2026

Copy link
Copy Markdown
Author

Edit: nevermind I was wrong about the bug. Ignore.

Original comment:

Actually I found a bug: the image on your computer gets cropped when aspect ratio is enabled. Let me look into this.

@yanthomasdev yanthomasdev left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM! Good work! Could you also make a PR in the decap-website repo adding the necessary docs for this feature? Thanks.

@evan6seven

Copy link
Copy Markdown
Author

LGTM! Good work! Could you also make a PR in the decap-website repo adding the necessary docs for this feature? Thanks.

Sure, I made one: decaporg/decap-website#167

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

3 participants