Skip to content

Instantly share code, notes, and snippets.

@thespacedoctor
Last active May 5, 2021 15:59
Show Gist options
  • Save thespacedoctor/cef1012b49635e4cbcb2556d84e99881 to your computer and use it in GitHub Desktop.
Save thespacedoctor/cef1012b49635e4cbcb2556d84e99881 to your computer and use it in GitHub Desktop.
[Adventures with Pillow, the Python Image Library] #pillow #python #image

The blog-post explaining these files can be found here.

from PIL import Image, ImageDraw, ImageChops, ImageFont
im = Image.open(
"color_igr_ra70.602710_dec-21.724330_arcsec600_skycell0812.050.jpeg")
# DETERMINE THE SIZE OF THE IMAGE
imWidth, imHeight = im.size
# THE CROSS HAIRS SHOULD BE 1/6 THE LENGTH OF THE SMALLEST DIMENSON
chLen = int(min(imWidth, imHeight) / 6)
# THE GAP IN THE CENTRE SHOULD BE 1/60 OF THE LENGTH OF THE SMALLEST DIMENSON
gapLen = int(min(imWidth, imHeight) / 60)
# LINE WIDTH SHOULD BE EASILY VIEWABLE AT ALL SIZES - 0.2% OF THE WIDTH SEEMS GOOD
# SEEMS FINE
lineWidth = int(max(imWidth, imHeight) / 500)
lines = []
l = (imWidth / 2 - gapLen - chLen, imHeight /
2, imWidth / 2 - gapLen, imHeight / 2)
lines.append(l)
l = (imWidth / 2 + gapLen, imHeight /
2, imWidth / 2 + gapLen + chLen, imHeight / 2)
lines.append(l)
l = (imWidth / 2, imHeight /
2 - gapLen - chLen, imWidth / 2, imHeight / 2 - gapLen)
lines.append(l)
l = (imWidth / 2, imHeight /
2 + gapLen, imWidth / 2, imHeight / 2 + gapLen + chLen)
lines.append(l)
# DETERMINE THE BEST COLOR FOR LINES
from PIL import ImageChops
im = ImageChops.invert(im)
im = im.convert("L")
tmp = im.resize((1, 1), resample=3)
tmp = ImageChops.invert(tmp)
bestColor = tmp.getcolors()[0][1]
# GENERATE THE DRAW OBJECT AND DRAW THE CROSSHAIRS
draw = ImageDraw.Draw(im)
draw.line(l, fill=bestColor, width=lineWidth)
for l in lines:
draw.line(l, fill=bestColor, width=lineWidth)
from PIL import Image, ImageDraw, ImageChops, ImageFont
# DRAW A SCALEBAR ON THE IMAGE
physicalWidth = 600 # WIDTH IN ARCSEC
startRatio = 0.3
sbPhysicalWidth = physicalWidth * startRatio
sbPixelWidth = imWidth * startRatio
# IF ON THE DEGREE SCALE
if sbPhysicalWidth > 3600:
divider = 3600
unit = "degree"
# IF ON THE ARCMIN SCALE
elif sbPhysicalWidth > 60:
divider = 60.
unit = "arcmin"
# IF ON THE ARCSEC SCALE
else:
divider = 1.
unit = "arcsec"
# FIND THE WIDTH OF THE BAR TO THE NEAREST WHOLE NUMBER ON GIVEN SCALE
tmpWidth = sbPhysicalWidth / divider
displayPhysicalWidth = int(sbPhysicalWidth / divider)
ratio = displayPhysicalWidth / tmpWidth
sbPhysicalWidth = int(sbPhysicalWidth * ratio)
sbPixelWidth = int(sbPixelWidth * ratio)
# DRAW THE SCALEBAR
l = (imWidth / 20, imHeight - imHeight / 20,
imWidth / 20 + sbPixelWidth, imHeight - imHeight / 20)
draw.line(l, fill=bestColor, width=lineWidth)
# ADD SCALE TEXT
text = """%(displayPhysicalWidth)s %(unit)s""" % locals()
fontsize = int(imWidth / 40)
font = ImageFont.truetype("source-sans-pro-regular.ttf", fontsize)
draw.text((imWidth / 20, imHeight - imHeight / 20 - fontsize * 1.3), text, fill=bestColor,
font=font, anchor=None)
# ADD ORIENTATION INDICATOR
lines = []
lineLength = int(min(imWidth, imHeight) / 20)
l = (imWidth - imWidth / 20 - lineLength, imHeight - imHeight / 20,
imWidth - imWidth / 20, imHeight - imHeight / 20)
lines.append(l)
l = (imWidth - imWidth / 20, imHeight - imHeight / 20,
imWidth - imWidth / 20, imHeight - imHeight / 20 - lineLength)
lines.append(l)
for l in lines:
draw.line(l, fill=bestColor, width=lineWidth)
# ADD SCALE TEXT
draw.text((imWidth - imWidth / 20 - fontsize * 0.3, imHeight - imHeight / 20 - lineLength - fontsize * 1.3), "N", fill=bestColor,
font=font, anchor=None)
draw.text((imWidth - imWidth / 20 - lineLength - fontsize * 0.8, imHeight - imHeight / 20 - fontsize * 0.6), "E", fill=bestColor,
font=font, anchor=None)
del draw
# ADD THE PS1 LOGO
wmHeight = int(max(imWidth, imHeight) / 20)
imagePath = "ps1.png"
logo = Image.open(imagePath)
(logoWidth, logoHeight) = logo.size
wmWidth = int((wmHeight / float(logoHeight)) * logoWidth)
logo = logo.resize((wmWidth, wmHeight), resample=3)
# CREATE A TRANSPARENT IMAGE THE SIZE OF THE ORIGINAL IMAGE - PASTE THE
# LOGO WHERE REQUIRED
logoPH = Image.new("RGBA", (imWidth, imHeight), color=(0, 0, 0, 0))
logoPH.paste(logo, box=(imHeight / 25, imHeight / 25))
# NOW TONE DOWN THE OPACITY
trans = Image.new("RGBA", (imWidth, imHeight), color=(0, 0, 0, 0))
logo = Image.blend(trans, logoPH, alpha=0.75)
# ADD THE WATERMARK STAMP TO THE ORIGINAL IMAGE
im = Image.alpha_composite(im.convert("RGBA"), logo)
# ADD A TRANSIENT MARKER
draw = ImageDraw.Draw(im)
xy1 = (imWidth / 2 - imWidth / 300, imWidth / 2 - imWidth / 300,
imWidth / 2 + imWidth / 300, imWidth / 2 + imWidth / 300)
xy2 = (imWidth / 2 - imWidth / 170, imWidth / 2 - imWidth / 170,
imWidth / 2 + imWidth / 170, imWidth / 2 + imWidth / 170)
draw.arc(xy2, 0, 360, fill="#dc322f")
draw.pieslice(xy1, 0, 361, fill="#dc322f")
im.show()
# im.save("new-stamp.png")
This file has been truncated, but you can view the full file.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment