Skip to content

Instantly share code, notes, and snippets.

@Sh4pe
Created June 30, 2020 14:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Sh4pe/6d1ab38c9aa530553ecc24b0bb5cf080 to your computer and use it in GitHub Desktop.
Save Sh4pe/6d1ab38c9aa530553ecc24b0bb5cf080 to your computer and use it in GitHub Desktop.
Draw on background image in Julia using Cairo.jl
using FileIO
using Images
import Cairo
function with_background(f, filename::String)
ctx = nothing
surf = nothing
try
img_raw = load(filename)
surf = Cairo.CairoImageSurface(convert.(ARGB32, img_raw))
ctx = Cairo.CairoContext(surf)
f(ctx, surf)
finally
if !isnothing(surf)
Cairo.finish(surf)
Cairo.destroy(surf)
end
if !isnothing(ctx)
Cairo.destroy(ctx)
end
end
end
struct Path
points::Vector{Tuple{Real,Real}}
function Path(pts)
@assert length(pts) >= 3
new(pts)
end
end
"""
draw_paths_on_image(img, paths; color_rgba, width)
Draws paths on image and returns result as Matrix of color values.
"""
function draw_paths_on_image(image::String, paths::Union{Path,Vector{Path}}; color_rgba=(1,0,0,1), width=5)
@assert width >= 1
if isa(paths, Path)
return draw_paths_on_image(image, [paths], color_rgba=color_rgba, width=width)
end
with_background(image) do ctx, surf
Cairo.set_source_rgba(ctx, color_rgba[1], color_rgba[2], color_rgba[3], color_rgba[4])
Cairo.set_line_width(ctx, width)
# Note the x, y "flip" here
for path in paths
Cairo.new_path(ctx)
first_point = path.points[1]
Cairo.move_to(ctx, first_point[2], first_point[1])
for point in path.points[2:end]
Cairo.line_to(ctx, point[2], point[1])
end
Cairo.line_to(ctx, first_point[2], first_point[1])
Cairo.stroke(ctx)
end
surf.data
end
end
### example
let
filename = "img.png"
paths = Path([(1,1), (100, 100), (200,100)])
draw_paths_on_image(filename, paths, color_rgba=(1,0,0,0.2), width=3)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment