{"id":15405698,"url":"https://github.com/zverok/xkcdize","last_synced_at":"2026-03-06T12:33:55.798Z","repository":{"id":33611532,"uuid":"37263724","full_name":"zverok/xkcdize","owner":"zverok","description":"XKCD-like picture distortion in Ruby and RMagick","archived":false,"fork":false,"pushed_at":"2015-06-12T09:57:42.000Z","size":346,"stargazers_count":45,"open_issues_count":2,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-17T13:57:04.650Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":"f0rb1dd3n/Reptile","license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/zverok.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-06-11T13:48:11.000Z","updated_at":"2022-11-26T15:00:12.000Z","dependencies_parsed_at":"2022-07-12T09:51:46.249Z","dependency_job_id":null,"html_url":"https://github.com/zverok/xkcdize","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/zverok/xkcdize","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zverok%2Fxkcdize","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zverok%2Fxkcdize/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zverok%2Fxkcdize/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zverok%2Fxkcdize/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/zverok","download_url":"https://codeload.github.com/zverok/xkcdize/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zverok%2Fxkcdize/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30176301,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-06T11:48:51.886Z","status":"ssl_error","status_checked_at":"2026-03-06T11:48:51.460Z","response_time":250,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-01T16:18:17.514Z","updated_at":"2026-03-06T12:33:55.779Z","avatar_url":"https://github.com/zverok.png","language":"Ruby","funding_links":[],"categories":[],"sub_categories":[],"readme":"This is a small experimental script to play with Ruby and images.\n\nIt just takes some image and converts makes it \"[xkcd](http://xkcd.com/)-like\" (effect of\nhandwritedness).\n\n**Before:**\n\n\u003cimg src=\"https://raw.github.com/zverok/xkcdize/master/image.png\"\u003e\n\n**After:**\n\n\u003cimg src=\"https://raw.github.com/zverok/xkcdize/master/image-xkcd.png\"\u003e\n\nThe story behind the script is simple. I've just read an excellent blog \n[post](http://blog.wolfram.com/2012/10/05/automating-xkcd-diagrams-transforming-serious-to-funny/)\nby Wolfram guy Vitaliy Kaurov, where he explains, how can you have\nxkcd-style charts in Wolfram Mathematica. Most of ideas there are fairly\nstraighforward (set bold style for lines, add labels, use appropriate fonts),\nbut there was some image distortion idea, which makes any graphics look\n\"pencil-drawn\".\n\nAnd there, I've just thinking \"Ruby **is** the best language evaaar, if\nI can do the same thing, reproduce this beautiful algo, with the same\nbrevity and elegance.\n\nLook for yourself, if I could!\n\nWolfram version:\n\n\u003cimg src=\"https://raw.github.com/zverok/xkcdize/master/xkcd-distort-wolfram.png\"\u003e\n\nRuby version (not the best one, see below!):\n\n```ruby\ndef xkcdize(src)\n  distorters = 2.times.map{\n    Image.random(src.columns, src.rows).adaptive_blur(10, 5)\n  }\n\n  src.fx('p{i+15*(0.5-u[1]),j+15*(0.5-u[2])}', *distorters)\nend\n```\n\nThe algo is the same. Look at commented code into\n[xkcdize.rb](https://github.com/zverok/xkcdize/blob/master/xkcdize.rb)\n\nTo be fair, the solution was not easy. The ImageMagick fx-script (which\nis passed to `Image#fx` method) was hard to guess, and it's not a Ruby,\njust a bit of RMagick internal script inside mine.\n\nYet it is all still pretty clean and laconic.\n\n### New: Clean Ruby Version\n\n\u003cstrike\u003eI've **almost** invented pure-Ruby version (without dirty `fx`) hack, now\nit looks like clean and understandable and debuggable Ruby. The algo seems to be EXACTLY the same, yet the result is pretty ugly\u003c/strike\u003e\n\nHere IS working Ruby version:\n\n```ruby\ndef xkcdize(src, shift=20)\n  distorters = 2.times.map{\n    Image.random(src.columns, src.rows).adaptive_blur(10, 5)\n  }\n\n  src.zip(*distorters).map_to_image{|(s, dx, dy), col, row|\n    src.pixel_color_f(col+shift*(0.5-dx.to_f), row+shift*(0.5-dy.to_f))\n  }\nend\n```\n\nThe algo is EXACTLY the same, as well as the result:\n\n\u003cimg src=\"https://raw.github.com/zverok/xkcdize/master/image-xkcd2.png\"\u003e\n\nLook at code: [xkcdize2.rb](https://github.com/zverok/xkcdize/blob/master/xkcdize2.rb)\n\nIt seems, I also invented very useful functionality for RMagickImage:\n\n```ruby\nsrc.pixel_color_f(col, row)\n```\n\nWhen provided with non-integer coordinates, it returns pixel, which is\n**bilinear interpolation** of pixels near the coordinates. (Though, to\npush it in RMagick, it should respect `Image#pixel_interpolation_method`\nsetting).\n\nAlso, take a look at `Image#zip(*other_images)` and `ImageList#map_to_image`\n-- they also seem to be of general usefulness: [rmagick_patch.rb](https://github.com/zverok/xkcdize/blob/master/rmagick_patch.rb)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzverok%2Fxkcdize","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzverok%2Fxkcdize","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzverok%2Fxkcdize/lists"}