Here is a quick example of drawing it using primitives with Luxor.jl
using Luxor
function b()
Drawing(300, 300, "hello-world.png")
background("black")
sethue("white")
#Luxor.scale(1,1)
Luxor.translate(150, 30)
Luxor.rotate(10 * pi / 180)
w = 40
h = 200
rect(O, w, h, :fill)
finish()
preview()
end

Now, instead of drawing it directly with Luxor you can extract the transformation matrix and use it somewhere else.
using Plots
using GR
using LinearAlgebra
gr(size = (300, 300), legend = false)
function a(transform=Matrix{Int}(I, 3, 3))
side = 300
width = side
height = side
xs = [string("x", i) for i = 1:width]
ys = [string("y", i) for i = 1:height]
z = float((1:height) * reshape(1:width, 1, :))
# Plots.heatmap(xs, ys, z, aspect_ratio = 1)
white = maximum(z)
# Draw a rectangle with a rotation matrix applied
for x in 0:40
for y in 0:200
t = transform*[x;y;1]
z[round(Int, t[2]), round(Int, t[1])] = white
end
end
Plots.heatmap(xs, ys, z, aspect_ratio = 1)
end
using Luxor
function b()
Drawing(300, 300, "hello-world.png")
background("black")
sethue("white")
#Luxor.scale(1,1)
Luxor.translate(100, 60)
Luxor.rotate(-10 * pi / 180)
w = 40
h = 200
rect(O, w, h, :fill)
finish()
preview()
tranformation_matrix = Luxor.cairotojuliamatrix(Luxor.getmatrix())
a(tranformation_matrix)
end
Note this leaves stray pixels, because my for loop isn't efficient at rasterizing the fill. Accessing pixel data out of Luxor may be better, or using some other function that applies affine transformations to a matrix.

Caution about plots in julia:
Time to first plot is slow. And to do any real iterations on it, you should leverage Revise.jl
and save your test functions in a file and include it with includet("test.jl")
. Then your julia session is persistent and you only have to wait for your using
statements once.