swaywm / sway

i3-compatible Wayland compositor
https://swaywm.org
MIT License
14.64k stars 1.11k forks source link

Include higher resolution background images #3559

Open vidister opened 5 years ago

vidister commented 5 years ago

Heyho!

I love the default Sway Background Image. But the version shipped looks really bad on my 4k screens. Is it possible to include a 4k version? Or even better: Add the ability to render SVGs.

I would volunteer to create a 4k version and create a pull request if someone has a hint where I can find the needed assets for that.

David

cedws commented 5 years ago

SVG rendering would be really quite nice. I don't think many DEs/WMs support that (if any), and I don't think it would be too difficult to implement.

I'm sure you've checked in assets/ already. The logo SVG is in there, but the gradient background isn't.

cedws commented 5 years ago

Actually, swaybg already supports SVGs, I just tried it.

progandy commented 5 years ago

swaybg supports svg as long as librsvg is installed and compiled with the gdk-pixbuf loader plugin.

I think swaybg currently loads an svg with the dimension specified in the file, though. It would be better to load the svg at the desired size. Related GdkPixbuf functions: gdk_pixbuf_get_file_info, gdk_pixbuf_new_from_file_at_scale

mstoeckl commented 3 years ago

The logo SVG is in there, but the gradient background isn't.

Replicating the gradient background in an SVG file is tricky, because the gradients in the PNG files are noticeably dithered. One of the ways to work around this is to overlay an SVG gradient (which is smooth, and if drawn as is would have light color banding) with a mostly-transparent tiled image. See for example the following images (which have .txt extension to get around a format whitelist)

Sway_Wallpaper_Blue_2048x1536.svg.txt Sway_Wallpaper_Blue_3840x2160.svg.txt

convert background.svg background.png will render them as PNGs of the listed size; due to the noise pattern, the resulting images are several MB large.

(Unfortunately, I used a random instead of pseudorandom pattern for the noise overlay; while the color banding seems to be hidden, the pattern yields faint stripes along the 0/45/90 degree axes. The overlay also made it harder to reconstruct the original gradient colors, so they are a bit off.)

mstoeckl commented 3 years ago

Another approach to making higher resolution images is to make a plain SVG image, render it to 16-bit-depth PNG, and then convert the 16-bit-depth image to 8-bit-depth while using dithering to avoid banding artifacts. This has the additional advantage that the image no longer has a visibly noisy background.

SVG image (still a bad replica): Sway_Wallpaper_Blue_1920x1080_SVG_export.svg.txt

To render this as a 16 bit PNG, I used a patched version of inkscape (https://gitlab.com/inkscape/inkscape/-/issues/1591#note_659878265) that relies on Cairo 1.17.4. There are probably easier ways to do this.

inkscape-patch -d 192 -C Sway_Wallpaper_Blue_1920x1080_SVG_export.svg --export-png-color-mode=RGB_16 -o output.png

Then loading the image in recent GIMP, invoking Image > Encoding > 8 bit integer, setting the layer dithering to "Blue Noise", and exporting, produces a reasonably clean image. Unfortunately, it is 4 MB large, and thus almost as large as all the other wallpapers combined.

wallpaper-3840x2160.png