Last active
February 17, 2022 00:42
-
-
Save mguid65/0c4c0abb999360a214e179766b897d5f to your computer and use it in GitHub Desktop.
Center and fit points to a box maintaining aspect ratio
This file contains 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
{ | |
"cells": [ | |
{ | |
"cell_type": "code", | |
"execution_count": 76, | |
"id": "cf059133", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"Scale Factor: 0.08333333333333333\n" | |
] | |
}, | |
{ | |
"data": { | |
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAG4AAABuCAIAAABJObGsAAABi0lEQVR4nO3dsQ6DMAwAUVLx3xVfng6pGCK2npzYvVsYQU8OQSxpvfertcN+7hyXd+9rnyN7V2uv1c9QJymxilNerYXtBGUpB2LkHnCG3SmmewbjN9I6lANx4adIBcrliKPElAvX8mMpKTcZw6lMlLuN4VQOyj3HcGp3yhSIo00pN1/Lj21HmWgMp3ahzDiGU+sp847h1ErKMoijBZQF1vJjoZTFxnAqiLI24iju129tx6PwX/T4pMSSEktKLCmxpMSSEktKLCmxpMSSEktKLCmxpMSSEktKLCmxpMSSEktKLCmxpMSSEktKLCmxpMSSEktKLCmxpMSSEktKLCmxpMSSEktKLCmxpMSSEktKLCmxpMSSEktKLCmxpMSSEktKLCmxpMSSEktKLCmxpMSSEktKLCmxpMSSEktKLCmxpMSSEktKLCmxpMSSEktKLCmxpMSSEktKLCmxpMSSEktKLCmxpMSSEktKLCmx4s4mu093q1oQZfnTtA4XOJiUWN8FXv5FFlDrf/AWi+kD3ntFCRTdjrwAAAAASUVORK5CYII=\n", | |
"text/plain": [ | |
"<PIL.Image.Image image mode=RGB size=110x110 at 0x7F3B46529B20>" | |
] | |
}, | |
"metadata": {}, | |
"output_type": "display_data" | |
} | |
], | |
"source": [ | |
"from IPython.core.display import Image, display\n", | |
"from PIL import Image, ImageDraw\n", | |
"\n", | |
"import PIL\n", | |
"\n", | |
"\n", | |
"def first_quadrant_offset(points):\n", | |
" offset = [0.0, 0.0]\n", | |
" \n", | |
" x_min = min([x for x, _ in points])\n", | |
" y_min = min([y for _, y in points])\n", | |
" \n", | |
" if x_min < 0:\n", | |
" offset[0] = -x_min\n", | |
" \n", | |
" if y_min < 0:\n", | |
" offset[1] = -y_min\n", | |
" \n", | |
" return offset\n", | |
"\n", | |
"\n", | |
"def contain_points(points, size):\n", | |
" scale_factor = 1.0\n", | |
" offset = [0.0, 0.0]\n", | |
" \n", | |
" x_list = [x for x, _ in points]\n", | |
" x_min, x_max = (min(x_list), max(x_list))\n", | |
" \n", | |
" y_list = [y for _, y in points]\n", | |
" y_min, y_max = (min(y_list), max(y_list))\n", | |
" \n", | |
" x_dist = y_max - y_min\n", | |
" y_dist = x_max - x_min\n", | |
" \n", | |
" x_ratio = size[0] / x_dist\n", | |
" y_ratio = size[1] / y_dist\n", | |
" \n", | |
" if x_ratio <= y_ratio:\n", | |
" ## ratio from x to new range x takes precedent\n", | |
" offset[0] = 0.5 * (size[1] - (x_ratio * y_dist))\n", | |
" return x_ratio, offset[0], offset[1]\n", | |
" else:\n", | |
" ## ratio from y to new range y takes precedent\n", | |
" offset[1] = 0.5 * (size[0] - (y_ratio * x_dist))\n", | |
" return y_ratio, offset[0], offset[1] \n", | |
"\n", | |
"img_size = (110.0, 110.0)\n", | |
"img_border_offset = 5.0\n", | |
"\n", | |
"points = [(0.0, 0.0), (500.0, 0.0), (500.0, 0.0), (500.0, 1200.0), (500.0, 1200.0), (0.0, 1000.0), (0.0, 1000.0), (0.0, 0.0)]\n", | |
" \n", | |
"x_quad_offset, y_quad_offset = first_quadrant_offset(points)\n", | |
"\n", | |
"points = [(x + x_quad_offset, y + y_quad_offset) for x, y in points]\n", | |
"\n", | |
"scale_factor, x_center_offset, y_center_offset = contain_points(points, (img_size[0] - (2 * img_border_offset), img_size[1] - (2 * img_border_offset)))\n", | |
"\n", | |
"print(\"Scale Factor: {}\".format(scale_factor))\n", | |
"\n", | |
"points = [((x * scale_factor) + img_border_offset + x_center_offset, (y * scale_factor) + img_border_offset + y_center_offset) for x, y in points]\n", | |
"\n", | |
"im = Image.new('RGB', (110, 110),(255,255,255))\n", | |
"\n", | |
"draw = ImageDraw.Draw(im)\n", | |
"# Draw border so we can see how big the box is\n", | |
"draw.polygon(((1.0,1.0), (1.0, im.size[1]-1), (im.size[0]-1, im.size[1]-1), (im.size[0]-1, 1.0)), outline=128)\n", | |
"\n", | |
"for p1, p2 in zip(points[::2], points[1::2]):\n", | |
" draw.line((p1, p2), fill=128)\n", | |
"\n", | |
"\n", | |
"im = PIL.ImageOps.flip(im)\n", | |
"\n", | |
"display(im)\n" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"id": "d6a61cc3", | |
"metadata": {}, | |
"outputs": [], | |
"source": [] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"id": "93454221", | |
"metadata": {}, | |
"outputs": [], | |
"source": [] | |
} | |
], | |
"metadata": { | |
"kernelspec": { | |
"display_name": "Python 3 (ipykernel)", | |
"language": "python", | |
"name": "python3" | |
}, | |
"language_info": { | |
"codemirror_mode": { | |
"name": "ipython", | |
"version": 3 | |
}, | |
"file_extension": ".py", | |
"mimetype": "text/x-python", | |
"name": "python", | |
"nbconvert_exporter": "python", | |
"pygments_lexer": "ipython3", | |
"version": "3.9.7" | |
} | |
}, | |
"nbformat": 4, | |
"nbformat_minor": 5 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment