Skip to content

Commit

Permalink
Add "How to get a transparent background" page (#3236)
Browse files Browse the repository at this point in the history
* Add "How to get a transparent background" page

* use `clear = true` in Figure because it's always top-level

* use transparency in glmakie example

* show non-transparent example first

* change title

* change to How-Tos
  • Loading branch information
jkrumbiegel authored Sep 25, 2023
1 parent 32980ec commit ed836a0
Show file tree
Hide file tree
Showing 5 changed files with 87 additions and 2 deletions.
1 change: 1 addition & 0 deletions docs/_layout/masthead.html
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
</li>
<li class="masthead__menu-item"><a href="/reference/">Reference</a></li>
<li class="masthead__menu-item"><a href="/tutorials/">Tutorials</a></li>
<li class="masthead__menu-item"><a href="/how-to/">How-Tos</a></li>
<li class="masthead__menu-item"><a href="/explanations/">Explanations</a></li>
<li class="masthead__menu-item"><a href="/api/">API</a></li>
<li class="masthead__menu-item"><a href="/news/">News</a></li>
Expand Down
2 changes: 1 addition & 1 deletion docs/explanations.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
@def order = 3
@def order = 4

# Explanations

Expand Down
5 changes: 5 additions & 0 deletions docs/how-to.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
@def order = 3

# How-Tos

{{list_folder how-to}}
79 changes: 79 additions & 0 deletions docs/how-to/save-figure-with-transparency.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# How to save a `Figure` with transparency

## CairoMakie

In CairoMakie, set the background color to `:transparent` (converts to `RGBAf(0, 0, 0, 0)`) to get a fully transparent background.
In the following examples, I use a partially transparent blue because a transparent background is indistinguishable from the usual white on a white page.

\begin{examplefigure}{svg = true}
```julia
using CairoMakie
CairoMakie.activate!() # hide

f = Figure(backgroundcolor = (:blue, 0.4))
Axis(f[1, 1], backgroundcolor = (:tomato, 0.5))
f
```
\end{examplefigure}

## GLMakie

For technical reasons, GLMakie's color buffer does not have an alpha component:

\begin{examplefigure}{}
```julia
using GLMakie
GLMakie.activate!() # hide
Makie.inline!(true) # hide

f = Figure(backgroundcolor = (:blue, 0.4))
Axis(f[1, 1], backgroundcolor = (:tomato, 0.5))
f
```
\end{examplefigure}


With the following trick you can still save an image with transparent background.
It works by setting two different background colors and calculating the foreground color with alpha from the difference.

```julia:transparent-glmakie
using GLMakie
GLMakie.activate!() # hide
Makie.inline!(true) # hide
function calculate_rgba(rgb1, rgb2, rgba_bg)::RGBAf
rgb1 == rgb2 && return RGBAf(rgb1.r, rgb1.g, rgb1.b, 1)
c1 = Float64.((rgb1.r, rgb1.g, rgb1.b))
c2 = Float64.((rgb2.r, rgb2.g, rgb2.b))
alphas_fg = 1 .+ c1 .- c2
alpha_fg = clamp(sum(alphas_fg) / 3, 0, 1)
alpha_fg == 0 && return rgba_bg
rgb_fg = clamp.((c1 ./ alpha_fg), 0, 1)
rgb_bg = Float64.((rgba_bg.r, rgba_bg.g, rgba_bg.b))
alpha_final = alpha_fg + (1 - alpha_fg) * rgba_bg.alpha
rgb_final = @. 1 / alpha_final * (alpha_fg * rgb_fg + (1 - alpha_fg) * rgba_bg.alpha * rgb_bg)
return RGBAf(rgb_final..., alpha_final)
end
function alpha_colorbuffer(figure)
scene = figure.scene
bg = scene.backgroundcolor[]
scene.backgroundcolor[] = RGBAf(0, 0, 0, 1)
b1 = copy(colorbuffer(scene))
scene.backgroundcolor[] = RGBAf(1, 1, 1, 1)
b2 = colorbuffer(scene)
scene.backgroundcolor[] = bg
return map(b1, b2) do b1, b2
calculate_rgba(b1, b2, bg)
end
end
f = Figure(backgroundcolor = (:blue, 0.4))
Axis(f[1, 1], backgroundcolor = (:tomato, 0.5))
f
save(joinpath(@OUTPUT, "transparent.png"), alpha_colorbuffer(f)) # hide
save("transparent.png", alpha_colorbuffer(f))
```

\fig{transparent.png}
2 changes: 1 addition & 1 deletion src/figures.jl
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ function Figure(; kwargs...)

kwargs_dict = Dict(kwargs)
padding = pop!(kwargs_dict, :figure_padding, theme(:figure_padding))
scene = Scene(; camera=campixel!, kwargs_dict...)
scene = Scene(; camera=campixel!, clear = true, kwargs_dict...)
padding = convert(Observable{Any}, padding)
alignmode = lift(Outside to_rectsides, padding)

Expand Down

0 comments on commit ed836a0

Please sign in to comment.