The blog-post explaining these files can be found here.
Last active
May 5, 2021 15:59
-
-
Save thespacedoctor/cef1012b49635e4cbcb2556d84e99881 to your computer and use it in GitHub Desktop.
[Adventures with Pillow, the Python Image Library] #pillow #python #image
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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