-
Notifications
You must be signed in to change notification settings - Fork 17.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
x/image/webp: support for WebP Encoding #45121
Comments
cc @nigeltao |
A WebP encoder would be a lot of work. If someone wants to write one, that would be great. But as far as I know nobody is working on that. |
That's a shame, whilst I understand that it may be a bit of work, it feels like it should be out of the box considering webp and go are both made by you guys! Adding C bindings when converting to webp using third party packages can be messy, as well as using the executables. I would love to offer a hand to contribute to the /x/image library but wouldn't know where to start. |
It's not a bit of work. As Ian said, it's a lot of work. :-) |
The good news is that image encoding is much less of a security minefield than image decoding is, simply because the input format (a bitmap) is far, far simpler. That said, have you considered ImageFlow? It’s free software (AGPL) available as both a daemon and a library. Commercial licenses are also available. |
This comment was marked as duplicate.
This comment was marked as duplicate.
This comment was marked as duplicate.
This comment was marked as duplicate.
This comment was marked as spam.
This comment was marked as spam.
This comment was marked as duplicate.
This comment was marked as duplicate.
Starting a new website project with a Go backend and was planning on using WebP for image thumbnails and it's really sad to see that there's no native encoder.. :( I would really like to avoid using C bindings (due to performance and memory safety concerns), but it seems that's the only option at the moment, except for executing the official I also considered using Rust, but that's way too advanced for me. Edit: I found https://github.com/nickalie/go-webpbin which seems quite decent. haven't tested it yet though. |
This comment was marked as duplicate.
This comment was marked as duplicate.
This comment was marked as duplicate.
This comment was marked as duplicate.
This comment was marked as duplicate.
This comment was marked as duplicate.
This comment was marked as duplicate.
This comment was marked as duplicate.
This comment was marked as off-topic.
This comment was marked as off-topic.
@ex-tag considering the shift with Intel and Nvidia recently and major providers using AV1 and particularly AVIF for websites, future steps for supporting these fantastic encoders would be hugely beneficial for the stdlib. But can appreciate its not a small job. |
Could go-libwebp by Jack Mordaunt offer a potential solution? I'm aware that rewriting libwebp in Go would be quite time-consuming, but Jack Mordaunt utilized ccgo and was able to port the libwebp C code to native Go code, making it functional, if I understand correctly. I'm not an expert, and I'm unsure of any potential risks this approach may present, but I wanted to share the idea. @JackMordaunt |
I think there is a better solution. Example may use c-bindings from library on C language. |
Thanks for the reference! Yes, it's functional. However there's a lot of downside to the transpilation approach which bars it from being anything official.
For anyone interested, |
Finally! The native solution - https://github.com/HugoSmits86/nativewebp |
looks like few lines of code one could write over the weekend. so it was not about a lot of work but rather just reading the spec, i assume... gj. |
@ainsleyclark thanks for the mention! @ivanjaros Haha, I tackled most of this over my Christmas break 😄 , and it ended up being far more work than the number of lines of code might suggest. This is indeed a default implementation of the specs, however I had to dig into a lot of specialized topics, and much of that effort isn’t reflected in the current implementation. The WebP format relies heavily on custom algorithms rather than standard ones; for example, it uses canonical Huffman encoding with a specialized table instead of standard Huffman encoding. While the spec provides a default implementation, creating an optimal Huffman tree based on pixel data requires extensive study and effort. I decided to release the project because, for my use case, achieving lossless encoding comparable to PNG was good enough. That said, I’ll continue improving the encoder over time.. |
@HugoSmits86 i have my fair share of experience trying to write code based on the official specification. i know the pain. great work and i hope it will catch on. though i have skipped webp and moved to avif which i produce with vips. i was tired of lack of native image support in Go for modern formats so i just bit the bullet and moved on altogether. again, great job! |
Awesome! Is there a chance that nativewebp could become x/image/webp? Thanks for the great work, @HugoSmits86! |
@wjkoh I’m not sure how to go about making that happen. If there’s a process or interest from the Go team, I’d be happy to explore it! |
@nigeltao @dmitshur @rolandshoemaker could you please advise on how to submit a new feature to x/image/webp? |
I don't think it would make sense to integrate this until it also supports the lossy part of the spec (which is what makes webp a viable jpeg replacement, and incidentally is 95% of the complexity of the format. There's a reason libwebp is 50k lines of code). |
@ALTree Fair point, but WebP is also a container format supporting VP8I, VP8X, and VP8L. Partial support is better than nothing, especially for specific use cases. For instance, one client required WebP output, and while most accept JPEG or PNG, nativewebp let me meet their needs without overhauling my pipeline. Even limited functionality can solve real-world problems. |
Exactly. My use-case. |
@ALTree Why is lossy support needed? Are lossless files too large? |
I am curious to know more about this. What client is this that requires only webp output, but does not support jpeg/png? How popular is it? |
Take this 3.0MB jpg image of Castello Estense in Ferrara. Converting it to a webp file in lossy mode with
Converting it to a lossless webp (again at
One may argue that a lossless conversion makes no sense in this scenario, since webp in lossless mode is supposed to be a png replacement and here we have a jpg image, but that's my point: it makes no sense to serve a VP8L webp in this case. If a client asks for a webp image hoping to save some bandwidth over jpeg, he won't be happy to receive a lossless webp that is more than 2 times the size of what a jpeg would have been. In fact, if lossless webp is all you support, in this scenario you'd be better off ignoring the webp preference and serving the jpg image itself. webp is intended to be both a png and a jpg replacement, with its lossless and lossy modes respectively. Someone interested in using the format will expect an encoder in the standard library to support both. |
I have tried with a PNG file (1,1Mb) |
@agnivade The client is an enterprise with a complex pipeline of 100+ scripts and tools for after-production image processing. They use lossless WebP to avoid quality loss from repeated saves across steps. My tool integrates into this on-premise setup, where file size and/or network traffic isn’t an issue. Switching to PNG or another format would require major changes, including custom metadata handling, needing approval from multiple departments; a lengthy process that could risk the deal. Therefore it was easier for me to just build nativewebp and meet their needs directly and avoid these complications.
@ALTree Your argument overlooks the timeline. While full support for all WebP modes would be ideal, after 14 years of Go and WebP, there’s still no support at all(!), and no signs of it changing. At this point, some support is far better than none. Those expecting support for all modes likely also expect Google’s language to have native WebP support by now. In both cases, they’ll be equally disappointed but not worse off. Meanwhile, there’s a significant group for whom VP8L support alone provides a viable solution. It’s about addressing current gaps rather than waiting indefinitely for a perfect solution. |
People don't seem to be asking the right question. There is only one question we need to ask: If we add a lossless WebP encoder to x/image/webp, who will be hurt, and who will benefit? The answer to the first question is no one, and to the second is everyone. Lossless WebP is already a better alternative to PNG and, in some cases, a deal-closer for Go users, as @HugoSmits86 mentioned above. At what cost? Only about 1,000 lines added to x/image/webp. Also, the more people see the new encoder, the greater the possibility that they will try to bring a lossy WebP encoder to fruition as well. |
One of the many applications of this new WebP lossless encoding for Go is Hugo. I only need to install ImageMagick to convert PNG files to WebP files for my Hugo-based website. I think this WebP encoding can allow Hugo to automatically transcode all PNG files to WebP without manual intervention, saving a ton of network traffic for all Hugo users worldwide. @bep @spf13 |
As to Hugo; Hugo's extended version (built with |
Probably OT but wouldn't it be better to just ship hugo with platform-native imagemagic/vips instead of cgo? Personally, I use vips cli to convert images into avif in my projects nowadays. And it is no different than using the old school imagemagic in php, for example, because you still need those libraries to be present in the machine and call them on one way or another, so why not just add one binary to handle all of the work and avoid cgo altogether? Not sure if imagemagic supports pipes, vips does not, but doing the work on file system seems a non-factor to me any way. In the end, Go is has GC and trying to use non-GC code will never not be a problem. |
@ivanjaros Image processing libraries are a security nightmare, which is probably why @bep is going to use WebAssembly. |
Hi there,
Currently we are able to decode webp images, which is great. But why can't we encode them?
Given that PSI is such a crucial factor for getting websites to rank, it's important that any server should be able to convert and serve webp images.
I have to jump through hoops at the moment and use the webp executable which is far from ideal.
Please please add an encoder!
Many many thanks.
The text was updated successfully, but these errors were encountered: