Mask images to circles
This commit is contained in:
parent
08266a2b91
commit
e806571ae2
19
common.typ
19
common.typ
|
@ -5,25 +5,10 @@
|
||||||
#let place_avatar(text_height, card) = {
|
#let place_avatar(text_height, card) = {
|
||||||
style(styles => {
|
style(styles => {
|
||||||
let text_offset = (text_height - measure(address_text(card), styles).height) / 2
|
let text_offset = (text_height - measure(address_text(card), styles).height) / 2
|
||||||
place(top + left,
|
|
||||||
block(
|
|
||||||
width: 1in,
|
|
||||||
height: text_offset,
|
|
||||||
fill: luma(180),
|
|
||||||
)
|
|
||||||
)
|
|
||||||
place(top + left,
|
|
||||||
dy: text_offset,
|
|
||||||
block(
|
|
||||||
width: 1in,
|
|
||||||
height: 4pt,
|
|
||||||
fill: luma(160),
|
|
||||||
)
|
|
||||||
)
|
|
||||||
place(
|
place(
|
||||||
top + left,
|
top + left,
|
||||||
dx: 0.1in,
|
dx: 0.1in,
|
||||||
dy: text_offset + 4pt - 0.15in,
|
dy: calc.max(text_offset + 4pt - 0.15in, 0pt),
|
||||||
image(card.avatar, width: 0.3in)
|
image(card.avatar, width: 0.3in)
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
@ -43,7 +28,6 @@
|
||||||
block(
|
block(
|
||||||
width: width - 0.5in,
|
width: width - 0.5in,
|
||||||
height: text_height,
|
height: text_height,
|
||||||
fill: luma(230),
|
|
||||||
align(
|
align(
|
||||||
start + horizon,
|
start + horizon,
|
||||||
address_text(card)
|
address_text(card)
|
||||||
|
@ -57,7 +41,6 @@
|
||||||
block(
|
block(
|
||||||
width: 100%,
|
width: 100%,
|
||||||
height: 1in/8,
|
height: 1in/8,
|
||||||
fill: luma(220),
|
|
||||||
align(
|
align(
|
||||||
top + center,
|
top + center,
|
||||||
text(font: "USPSIMBCompact", size: 12pt, card.imb)
|
text(font: "USPSIMBCompact", size: 12pt, card.imb)
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
packages = [
|
packages = [
|
||||||
typst
|
typst
|
||||||
python3
|
python3
|
||||||
python3Packages.autopep8
|
python3Packages.black
|
||||||
python3Packages.requests
|
python3Packages.requests
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
33
format.py
33
format.py
|
@ -1,5 +1,6 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
import argparse
|
import argparse
|
||||||
|
import base64
|
||||||
import csv
|
import csv
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
|
@ -19,19 +20,40 @@ def iso_code(s: str) -> str:
|
||||||
return s
|
return s
|
||||||
|
|
||||||
|
|
||||||
def get_avatar(url: str) -> str:
|
def get_orig_avatar(url: str, name: str) -> typing.Optional[bytes]:
|
||||||
if not os.path.exists("cache"):
|
if not os.path.exists("cache"):
|
||||||
os.mkdir("cache")
|
os.mkdir("cache")
|
||||||
name = url.split("?")[0].split("/")[-1]
|
|
||||||
if os.path.exists("cache/" + name):
|
if os.path.exists("cache/" + name):
|
||||||
return "cache/" + name
|
with open("cache/" + name, "rb") as infile:
|
||||||
|
return infile.read()
|
||||||
result = requests.get(url)
|
result = requests.get(url)
|
||||||
if result.ok:
|
if result.ok:
|
||||||
with open("cache/" + name, "wb") as outfile:
|
with open("cache/" + name, "wb") as outfile:
|
||||||
outfile.write(result.content)
|
outfile.write(result.content)
|
||||||
return "cache/" + name
|
return result.content
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def get_avatar(url: str) -> str:
|
||||||
|
name = url.split("?")[0].split("/")[-1]
|
||||||
|
if os.path.exists(f"cache/{name}.svg"):
|
||||||
|
return f"cache/{name}.svg"
|
||||||
|
avatar_raster = get_orig_avatar(url, name)
|
||||||
|
if avatar_raster is None:
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
|
svg_text = f"""<svg viewBox="0 0 480 480" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
|
<mask id="circle" width="480" height="480">
|
||||||
|
<circle cx="240" cy="240" r="240" fill="white"></circle>
|
||||||
|
</mask>
|
||||||
|
<image width="480" height="480" mask="url(#circle)"
|
||||||
|
xlink:href="data:;base64,{base64.b64encode(avatar_raster).decode("utf-8")}"></image>
|
||||||
|
</svg>"""
|
||||||
|
|
||||||
|
with open(f"cache/{name}.svg", "w") as svgfile:
|
||||||
|
svgfile.write(svg_text)
|
||||||
|
return f"cache/{name}.svg"
|
||||||
|
|
||||||
|
|
||||||
def get_country_name(
|
def get_country_name(
|
||||||
root: ET.ElementTree, destination: str, alt=None
|
root: ET.ElementTree, destination: str, alt=None
|
||||||
|
@ -51,8 +73,7 @@ def get_country_name(
|
||||||
parser = argparse.ArgumentParser(
|
parser = argparse.ArgumentParser(
|
||||||
prog="format", description="format postcards with latex"
|
prog="format", description="format postcards with latex"
|
||||||
)
|
)
|
||||||
parser.add_argument("template", help="template to use",
|
parser.add_argument("template", help="template to use", nargs="?", default="2card")
|
||||||
nargs="?", default="2card")
|
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"-o", "--origin", help="origin country code", default="us", type=iso_code
|
"-o", "--origin", help="origin country code", default="us", type=iso_code
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in a new issue