-
Notifications
You must be signed in to change notification settings - Fork 5
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
Script to build image #6
Comments
Perhaps one can iterate through all images in the folder, check the |
That's probably doable. With Images might be more portable, although Or we could say: "Do you want your organization to be in our list? Make sure your icon's a PNG?" ... 😄 |
This is awesome! Is it possible to align the names and either shorten the long ones or overflow to next line? Basically have everything fit to a grid? |
Another nice feature would be the aspect ratio of the whole image - to make it fit on different types of screens. |
I'll add aspect ratio tomorrow. And I think we can do better than Apple's crappy line breaking here...! 😃 |
Yes, we can certainly do better than Apple's line breaking. I almost wonder why they don't do that already. |
Another version, with more attention to layout. using Luxor, Images, FileIO
# script to make a grid of org logos
"""
get_nrows_ncols(N;
aspectratio=MathConstants.golden)
Return nrows, ncols for a list of length N to be arranged in
`aspectratio`.
"""
function get_nrows_ncols(N;
aspectratio=MathConstants.golden)
currentratio = a = b = N
for i in 1:N
a₁ = i
b₁ = convert(Int, ceil(N / a₁))
ratio = a₁/b₁
if abs(ratio - aspectratio) < abs(currentratio - aspectratio)
a = a₁
b = b₁
currentratio = ratio
end
end
return a, b
end
"""
textsplitcamelcasecentered(t, pos, width)
Draw text on a number of rows by splitting text at each uppercase letter.
"""
function textsplitcamelcasecentered(t, pos, width;
leading = 12)
# convert camelcase string
t1 = split(replace(t, r"([[:upper:]])" => s" \1"), ' ', keepempty=false)
t1 = join(t1, "\n")
tlines = textlines(t1, width)
y = pos.y
for i in 1:length(tlines)
wd = replace(tlines[i], " " => "")
te = textextents(wd)
text(wd, Point(pos.x, y), halign=:center)
y += leading
end
end
"""
buildimagedict!(orgnamelist, workingdir, imagedict)
Make a dictionary, use text list of organization names.
Download PNG images from github.
Store them in `workingdir`.
Fill and return dictionary `imagedict`.
"""
function buildimagedict!(orgnamelist, workingdir, imagedict)
orgnames = open(orgnamelist) do f
split(read(f, String))
end
sort!(orgnames, lt = (a, b) -> lowercase(a) < lowercase(b))
for o in orgnames
# download file if we haven't already
if !isfile(workingdir * o * ".png")
@info "downloading icon for $o"
download("https://github.com/" * o * ".png", workingdir * o * ".png")
end
end
iconlist = filter(f -> endswith(f, ".png"), readdir(workingdir))
for iconfile in iconlist
path = joinpath(workingdir, iconfile)
# add Cairo/Luxor image to dictionary
try
q = query(path)
if typeof(q) == File{DataFormat{:JPEG}}
@info " Converting $path to PNG..."
img = load(path)
save(path, img)
end
imagedict[iconfile] = readpng(path)
catch e
# will fail if github gives us a JPEG instead of a PNG
@warn "skipping $iconfile"
println("\t", e)
end
end
return imagedict
end
"""
draworgicon(imagedict, key)
Draw the icon at current origin. Since they might be transparent,
place on white background.
"""
function draworgicon(imagedict, key;
size=300)
@layer begin
sethue("white")
squircle(O, size/2, size/2, :fill, rt=0.1)
squircle(O, size/2, size/2, :clip, rt=0.1)
img = imagedict[key]
w, h = img.width, img.height
sf = max(w, h)
scale(size/sf * 0.95)
placeimage(img, O, centered=true, 1)
clipreset()
end
end
function main(fname, w, h;
orgnames = "/tmp/orgnames.txt",
workingdir = "/tmp/julia-org-logos/",
aspectratio = MathConstants.golden)
if !isdir(workingdir)
mkdir(workingdir)
end
# build the dictionary
imagedict = Dict{String, Any}()
buildimagedict!(orgnames, workingdir, imagedict)
# start the drawing
d = Drawing(w, h, fname)
origin()
background(0.1, 0.1, 0.2)
labelfontsize = 12
ncols, nrows = get_nrows_ncols(length(imagedict), aspectratio=aspectratio)
tiles = Tiler(w, h, nrows, ncols, margin=20)
@info "grid is $nrows rows by $ncols columns"
@info "to hold $(length(imagedict)) icons"
fontsize(labelfontsize)
for (n, k) in enumerate(sort(collect(keys(imagedict))))
@layer begin
translate(first(tiles[n]))
S = min(tiles.tileheight, tiles.tilewidth)/2
draworgicon(imagedict, k, size = S)
sethue("white")
txt = replace(k, ".png" => "")
txtpos = O + (0, tiles.tileheight/2 - labelfontsize)
textsplitcamelcasecentered(txt, txtpos, tiles.tilewidth, leading = 12)
end
end
finish()
return d
end
main("/tmp/julia-orgs-grid.svg", 1400, 1000, aspectratio=MathConstants.golden) |
This Julia script builds a grid of organization logos. There are a few issues.
Running this the first time shows a few icons that are actually JPEGs, which Cairo/Luxor doesn't handle:
A workaround is to get these files separately, then convert to PNG, then run the script again (which I did to make the image above).
The text was updated successfully, but these errors were encountered: