Created
February 9, 2019 22:08
-
-
Save tcyrus/2263d44ee98ff40935a0148a2dca4ae3 to your computer and use it in GitHub Desktop.
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
| { | |
| "cells": [ | |
| { | |
| "metadata": {}, | |
| "cell_type": "markdown", | |
| "source": "# Jdenticon Generation from F# Notebook\n\nI try to document all procedural generation for things like avatars. My latest avatar for \"tcyr.us\" is created using Jdenticon. Jdenticon has 3 official software impelementations: JavaScript, .NET, and PHP. The only one of those which had a supported Jupyter Kernel was .NET (via F#).\n\nThe catch is the implementation needs some hacks to get it working with F#." | |
| }, | |
| { | |
| "metadata": {}, | |
| "cell_type": "markdown", | |
| "source": "First things first, get the `Jdenticon-net` package via NuGet via Paket." | |
| }, | |
| { | |
| "metadata": { | |
| "trusted": true | |
| }, | |
| "cell_type": "code", | |
| "source": "#load \"Paket.fsx\"\nPaket.Package [ \"Jdenticon-net\" ]\n#load \"Paket.Generated.Refs.fsx\"", | |
| "execution_count": 8, | |
| "outputs": [] | |
| }, | |
| { | |
| "metadata": {}, | |
| "cell_type": "markdown", | |
| "source": "So far so good..." | |
| }, | |
| { | |
| "metadata": { | |
| "trusted": true | |
| }, | |
| "cell_type": "code", | |
| "source": "open Jdenticon\nopen Jdenticon.Rendering", | |
| "execution_count": 9, | |
| "outputs": [] | |
| }, | |
| { | |
| "metadata": {}, | |
| "cell_type": "markdown", | |
| "source": "Custom identicon style can be found [here](https://jdenticon.com/icon-designer.html?config=2a4766ff10cd322d33552c41).\n\nThis was my attempt at porting the example code from C# to F#. This is somewhat hacky since some of the code doesn't actually translate well into an immutable model. Feel free to contact me if there is a better way to do any of this." | |
| }, | |
| { | |
| "metadata": {}, | |
| "cell_type": "markdown", | |
| "source": "First, `HueCollection` is in the `Jdenticon.Rendering` namespace. The sample code relies on exploiting collection initializers, something which works in C# but not F#. This uses a `let` binding expression as an ugly but functional solution (no pun intended)." | |
| }, | |
| { | |
| "metadata": { | |
| "trusted": true | |
| }, | |
| "cell_type": "code", | |
| "source": "let hues =\n let tmp = new HueCollection()\n tmp.Add(205.0f, HueUnit.Degrees)\n tmp", | |
| "execution_count": 10, | |
| "outputs": [] | |
| }, | |
| { | |
| "metadata": {}, | |
| "cell_type": "markdown", | |
| "source": "This code uses F# Property Initializer, the closest thing I could find to the C# Object Initializer." | |
| }, | |
| { | |
| "metadata": { | |
| "trusted": true | |
| }, | |
| "cell_type": "code", | |
| "source": "let style = new IdenticonStyle(Hues = hues,\n BackColor = Color.FromRgba(42, 71, 102, 255),\n ColorLightness = Range.Create(0.51f, 0.85f),\n GrayscaleLightness = Range.Create(0.44f, 0.65f),\n ColorSaturation = 0.50f,\n GrayscaleSaturation = 0.45f)", | |
| "execution_count": 11, | |
| "outputs": [] | |
| }, | |
| { | |
| "metadata": {}, | |
| "cell_type": "markdown", | |
| "source": "Since I couldn't use the Property Initializer here, I had to use another `let` binding expression." | |
| }, | |
| { | |
| "metadata": { | |
| "trusted": true | |
| }, | |
| "cell_type": "code", | |
| "source": "let avatar = \n let tmp = Identicon.FromValue(\"tcyr.us\", size=512)\n tmp.Style <- style\n tmp", | |
| "execution_count": 12, | |
| "outputs": [] | |
| }, | |
| { | |
| "metadata": {}, | |
| "cell_type": "markdown", | |
| "source": "Since `IfSharp` doesn't support SVG rendering directly, I improvised. I used `AddDisplayPrinter` to tell the `Display` function how to handle `Identicon` objects. Since browsers will render SVG inline, I can use the `\"text/html\"` option for `ContentType` and hope for the best." | |
| }, | |
| { | |
| "metadata": { | |
| "trusted": true | |
| }, | |
| "cell_type": "code", | |
| "source": "open IfSharp.Kernel.App\n\nAddDisplayPrinter (fun (id: Identicon) -> { ContentType = \"text/html\"; Data = id.ToSvg() })", | |
| "execution_count": 13, | |
| "outputs": [] | |
| }, | |
| { | |
| "metadata": { | |
| "trusted": true | |
| }, | |
| "cell_type": "markdown", | |
| "source": "Now, the moment of truth..." | |
| }, | |
| { | |
| "metadata": { | |
| "trusted": true | |
| }, | |
| "cell_type": "code", | |
| "source": "avatar", | |
| "execution_count": 14, | |
| "outputs": [ | |
| { | |
| "output_type": "execute_result", | |
| "execution_count": 14, | |
| "data": { | |
| "text/html": "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"512\" height=\"512\" viewBox=\"0 0 512 512\" preserveAspectRatio=\"xMidYMid meet\"><rect fill=\"#2a4766\" fill-opacity=\"1\" x=\"0\" y=\"0\" width=\"512\" height=\"512\"/><path fill=\"#c1d9ea\" d=\"M256 149L149 149L149 95.5ZM256 149L256 42L309.5 42ZM256 363L363 363L363 416.5ZM256 363L256 470L202.5 470ZM149 256L42 256L42 202.5ZM363 256L363 149L416.5 149ZM363 256L470 256L470 309.5ZM149 256L149 363L95.5 363Z\"/><path fill=\"#386e95\" d=\"M59.83369 95.49999a35.66631,35.66631 0 1,1 71.33263,0a35.66631,35.66631 0 1,1 -71.33263,0M380.8337 95.5a35.66631,35.66631 0 1,1 71.33263,0a35.66631,35.66631 0 1,1 -71.33263,0M380.8337 416.5a35.66631,35.66631 0 1,1 71.33263,0a35.66631,35.66631 0 1,1 -71.33263,0M59.83368 416.5a35.66631,35.66631 0 1,1 71.33263,0a35.66631,35.66631 0 1,1 -71.33263,0\"/><path fill=\"#7aaed2\" d=\"M175 175L246 175L246 246L175 246ZM337 175L337 246L266 246L266 175ZM337 337L266 337L266 266L337 266ZM175 337L175 266L246 266L246 337Z\"/></svg>" | |
| }, | |
| "metadata": {} | |
| } | |
| ] | |
| } | |
| ], | |
| "metadata": { | |
| "kernelspec": { | |
| "name": "ifsharp", | |
| "display_name": "F#", | |
| "language": "fsharp" | |
| }, | |
| "language_info": { | |
| "mimetype": "text/x-fsharp", | |
| "nbconvert_exporter": "", | |
| "name": "fsharp", | |
| "pygments_lexer": "", | |
| "version": "4.3.1.0", | |
| "file_extension": ".fs", | |
| "codemirror_mode": "" | |
| }, | |
| "language": "fsharp" | |
| }, | |
| "nbformat": 4, | |
| "nbformat_minor": 2 | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment