Skip to content

Instantly share code, notes, and snippets.

@christianp
Created August 1, 2019 18:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save christianp/8b005baa545de4cb1d945fbbe5366cfc to your computer and use it in GitHub Desktop.
Save christianp/8b005baa545de4cb1d945fbbe5366cfc to your computer and use it in GitHub Desktop.
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "code",
"execution_count": 138,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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\n",
"text/plain": [
"<PIL.Image.Image image mode=RGB size=200x200 at 0x7F877E771EB8>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"[0, 85, 170, 255]\n"
]
},
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAMgAAADIAgMAAADQNkYNAAAADFBMVEUAAABVVVWqqqr////Bf2LRAAACBElEQVR4nO2azX2DMAzF1e6QJTIFQ0RkB5YoS7BDcIdgnw5R19YHsl0uhmP0Dv7R1v8c9JSHMIVQCwBuCFn4yOsHDtBucaQbWXEKOIYF09XAe3RJylz6qyNtkTMXXlzftGTEipx0ly2OnEPscu/ftNywUP6xtdKRHiRw309BPYCy+TE7lGX+OcKay925nbm063GRHelDJJNnMF9oD/syshukyZGzCOlVDQiGhO/4I0iG6Qb59ojcwFTllHDPn7bF+Js22rzgSD8ivpgbAzT5wJksHe/IOSTd+MSXchSjCEHUpGBf8nfBES6yDK9caYI/c/9KuWdIu2N05Bryz5d09RU5mEWbI5eQtUhi5fbZgO9+eUnpvEVHWDMXGVEDtkHw6chlRKKBRA41TZyQOi4c6UIWTl1GHrs5JDvnkkyO0RGWjQVYZsbIHxhCJDXN70gfsmARF9TOUGTGglFUNb8jHUg14GIRHKzxwJe3RmbQYxOqryw8OTRIlLhwpA/Z3780vhQIplnWkQuI/lJSAe2eRxr5CGZzxIq8ByyJ5yrYH2bpdKD1xZFeZFUL9KDQnsXUoWeMjlxBqPLEcXBIHNsDGR59X94ZoSauUnbgA5ZqXpi43R05h6AEQiU7IwR+PyCiocGRfkTcmPjESyE1x864SfSC25EFbbjSbBWF/V8sNEwc6Uf+ALwgEQqBgifcAAAAAElFTkSuQmCC\n",
"text/plain": [
"<PIL.Image.Image image mode=P size=200x200 at 0x7F877E7FEFD0>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"Took 399 goes\n",
"[2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 1, 2, 1, 2, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, 2, 1, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 1, 2, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 1, 1, 0, 1, 2, 1, 1, 1, 0, 1, 2, 2, 2, 2, 2, 2, 2, 1, 2, 1, 2, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 2, 3, 2, 2, 1, 1, 1, 2, 2, 1, 2, 1, 2, 1, 2, 2, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 2, 2, 2, 3, 3, 2, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 2, 2, 2, 2, 2, 2, 1, 1, 1, 2, 1, 2, 1, 2, 2, 2, 2, 1, 2, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 2, 0, 1, 1, 1, 1, 1, 2, 1, 2, 2, 2, 3, 2, 2, 2, 2, 2, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 2, 1, 1, 0, 1, 2, 2, 0, 2, 3, 3, 2, 3, 2, 2, 2, 2, 2, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 3, 0, 1, 1, 2, 2, 2, 2, 2, 3, 2, 3, 2, 2, 2, 2, 2, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 2, 2, 2, 2, 2, 3, 2, 2, 3, 2, 3, 2, 3, 2, 2, 2, 2, 2, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 2, 2, 2, 2, 2, 3, 2, 1, 3, 2, 3, 2, 3, 2, 2, 2, 2, 2, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 2, 2, 2, 2, 2, 3, 1, 3, 3, 2, 3, 2, 2, 2, 1, 2, 2, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 2, 3, 3, 2, 2, 2, 2, 2, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 2, 1, 2, 2, 2, 3, 3, 3, 3, 2, 3, 2, 2, 2, 2, 2, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 2, 2, 2, 1, 3, 3, 3, 3, 3, 2, 2, 2, 2, 1, 2, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 3, 3, 3, 3, 2, 3, 2, 2, 0, 2, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 2, 2, 3, 3, 3, 3, 3, 3, 2, 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 2, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 2, 1, 1, 3, 3, 3, 3, 3, 3, 3, 2, 1, 1, 1, 1, 1, 2, 1, 2, 2, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, 2, 2, 1, 1, 2, 1, 2, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 2, 3, 3, 3, 3, 3, 3, 3, 2, 2, 1, 2, 1, 2, 1, 2, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 1, 2, 1, 1, 1, 2, 2, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 2, 1, 2, 2, 2, 2, 2, 2, 1, 2, 1, 2, 1, 1, 2, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 2, 1, 2, 2, 2, 2, 2, 1, 2, 1, 1, 1]\n"
]
},
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAMgAAADIAgMAAADQNkYNAAAADFBMVEUAAABVVVWqqqr////Bf2LRAAACBklEQVR4nO2azX2DMAzF1eyQJTIFQ0RkB5YoS7BDcIdgnw5R19YHsp1cDMfoHfyjrf856CkPYQqhFgBcEbLwntcvHKDd4kg3suIUcAwLpquB9+iSlLn0V0faImcuPLm+acmIFTnpJlscOYbY5d6/abliofxja6UjPUjgvp+CegBl82N2KMv8c4Q1y+4LX12ltOv7IjvSh0gmz2C+0B72ZWQ3SJMjRxHSsxoQDAk/8VeQDNMN8uMRuYGpyinhlj9ti/EvbbR5wZF+RHwxNwZo8oEzWTrekWNIuvGJL+UoRhGCqEnBvuTvgiNcZBleudIEX3L/SrlnSLtjdOQc8uJLuvqOHMyizZFTyFoksXL7bMB3v7ykdN6iI6yZi4yoAdsg+HDkNCLRQCKHmiZOSB0XjnQhC6cuI/fdHJKdc0kmx+gIy8YCLDNj5A8MIZKa5nekD1mwiAtqZygyY8EoqprfkQ6kGnCxCA7W+MaXj0Zm0GMTqq8sPDk0SJS4cKQP2d+/NL4UCKZZ1pETiP5SUgHtnkca+Qhmc8SKvAcsiecq2B9m6XSg9cWRXmRVC/Sg0J7F1KFHjI6cQajyxHFwSBzbAxm++758MkJNXKXswAcs1bwwcbs7cgxBCYRKdkYI/H5AREODI/2IuDHxiZdCao6dcZPoBbcjC9pwpdkqCvu/WGiYpC2OdCL/utgSPnhc2XEAAAAASUVORK5CYII=\n",
"text/plain": [
"<PIL.Image.Image image mode=P size=200x200 at 0x7F877E7FEFD0>"
]
},
"execution_count": 138,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"from sympy.ntheory import isprime\n",
"from PIL import Image\n",
"from random import randrange, choice\n",
"from math import log\n",
"import hitherdither\n",
"from IPython.display import display\n",
"from datetime import datetime\n",
"\n",
"w = 30\n",
"base = 4\n",
"im = Image.open('cp.png')\n",
"im = im.resize((w,w)).convert('L').convert('RGB')\n",
"display(im.resize((200,200)))\n",
"cols = [255*i//(base-1) for i in range(base)]\n",
"print(cols)\n",
"cols = [(c,c,c) for c in cols]\n",
"palette = hitherdither.palette.Palette(cols)\n",
"#for method in hitherdither.diffusion._DIFFUSION_MAPS.keys():\n",
"# print(method)\n",
"# img_dithered = hitherdither.diffusion.error_diffusion_dithering(\n",
"# im, palette, method=method, order=2)\n",
"# display(img_dithered.resize((200,200)))\n",
"im = hitherdither.diffusion.error_diffusion_dithering(\n",
" im, palette)\n",
"display(im.resize((200,200)))\n",
"\n",
"pixels = list(im.getdata())\n",
"pixels[-1] = 1\n",
"#print(pixels)\n",
"\n",
"def twiddle(d):\n",
" if d==0:\n",
" return 1\n",
" elif d==base-1:\n",
" return base-2\n",
" else:\n",
" return d+choice((-1,1))\n",
"\n",
"def moosh(pixels):\n",
" changes = 1\n",
" \n",
" goes = 0\n",
" while True:\n",
" #changes += 1\n",
" goes += 1\n",
" changed = pixels[:]\n",
" for i in range(changes):\n",
" n = randrange(len(changed)-1)\n",
" changed[n] = twiddle(changed[n])\n",
" s = ''.join(str(d) for d in changed)\n",
" n = int(s)\n",
" if isprime(n):\n",
" print(\"Took {} goes\".format(goes))\n",
" return changed\n",
"\n",
"pixels = moosh(pixels)\n",
"\n",
"im.putdata(pixels)\n",
" \n",
"im.resize((200,200))"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"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.7.3"
}
},
"nbformat": 4,
"nbformat_minor": 4
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment