{"id":243,"date":"2011-03-09T17:44:56","date_gmt":"2011-03-09T16:44:56","guid":{"rendered":"http:\/\/jimblackler.com\/blog\/?p=243"},"modified":"2011-03-09T17:44:56","modified_gmt":"2011-03-09T16:44:56","slug":"fortune-cookie-image-generator","status":"publish","type":"post","link":"https:\/\/jimblackler.com\/?p=243","title":{"rendered":"Fortune Cookie Image Generator"},"content":{"rendered":"<p>I&#8217;ve always enjoyed playing with meme image creation tools such as saysit.com and many others. When I couldn&#8217;t find a creation tool to make fake fortune cookie images I decided to build my own. It would also give me a chance to play with some HTML5 technology I&#8217;ve been looking at, specifically SVG images.<\/p>\n<p>The generator quite simply builds an image of a fortune cookie with a custom slogan provided by the user. You&#8217;ll find it at <a href=\"http:\/\/jim.ignitiondomain.com\/fc\">http:\/\/jim.ignitiondomain.com\/fc<\/a><\/p>\n<h2>How I built it<\/h2>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/jimblackler.com\/blog\/wp-content\/uploads\/2011\/03\/fc.png\" width=\"327\" height=\"329\" class=\"alignleft size-full wp-image-253\" srcset=\"https:\/\/jimblackler.com\/wp-content\/uploads\/2011\/03\/fc.png 327w, https:\/\/jimblackler.com\/wp-content\/uploads\/2011\/03\/fc-150x150.png 150w, https:\/\/jimblackler.com\/wp-content\/uploads\/2011\/03\/fc-298x300.png 298w\" sizes=\"auto, (max-width: 327px) 100vw, 327px\" \/><\/p>\n<p>Once I found a suitable fortune cookie image on Flikr (an excellent image from Flikr user cpstorm), and checked it had the right license (Creative Commons for modification) I merely had to remove the existing slogan on the image. Easy right? As it happens, Photoshop&#8217;s Content Aware Removal tool does a brilliant job at this kind of thing, and the operation barely took ten minutes.<\/p>\n<p>I then used Inkscape to make an SVG file that featured the image, plus a template for the replacement text. This involved picking a suitable font, laying down a path for the text based on the existing slogan, and carefully selecting a filter to get the &#8216;blotter paper&#8217; look. I was pretty pleased with the results, if feel the results are almost photorealistic.<\/p>\n<p>I simplified the SVG file as much as possible (Inkscape is excellent but it does include some redundant data that can be removed by hand).<\/p>\n<p>Next step was to host the SVG image in a generator html page, where the user could supply text that would be patched into the SVG. This worked great; on Chrome, Firefox and Opera. Safari doesn&#8217;t support filters so the blotter-paper text effect didn&#8217;t work. IE doesn&#8217;t support SVG at all right now (although it is coming in the next major release)<\/p>\n<p>So to support these browsers, and to allow the image to be saved as a .jpg file, I really needed the ability to generate the JPGs on the server side.<\/p>\n<p>It turns out this is very hard. I looked at ImageMagick which my web host supports. Unfortunately none of ImageMagick&#8217;s supported SVG engines has text paths, so the effect would be impossible.<\/p>\n<p>In the end I discovered Batik which is a superb Java-based SVG engine with transcoding abilities. The only problem is my current web host doesn&#8217;t support Java, and another option Google App Engine wouldn&#8217;t work because Batik uses multiple threads and App Engine does not allow that.<\/p>\n<p>I looked at options and found an inexpensive Java host just for this application, and purchased a three year package. This allows me to support all browsers, but use client rendering on Chrome, Firefox and Opera for a better experience. The Java servlet uses Batik to generate JPGs from the same SVG used to build the images in browsers, with the custom slogan passed on URL parameters.<\/p>\n<p>I also wanted to provide a great image hotlinking service that was as easy to use as possible. It wouldn&#8217;t be ideal to try to allow hotlinking on the generator site for a number of reasons, but since there are tons of image hosting sites out there for this kind of thing, the best thing would be to integrate with one of those. I&#8217;d seen something called &#8216;anonymous sideloading&#8217; from an image site called imgur.com, and this proved to be ideal. With one click I can load the images directly onto imgur via users&#8217;s browsers. The only tough bit was the restrictions that imager was putting on characters in the source image URL; specifically imgur&#8217;s side loader didn&#8217;t like the &#038; symbol or spaces. I needed to rejig the generator to take all the parameters as a single Base64 encoded JSON object. This made the URLs imgur friendly and the image hosting setup works a charm.<\/p>\n<p>Hope you enjoy the generator at <a href=\"http:\/\/jim.ignitiondomain.com\/fc\">http:\/\/jim.ignitiondomain.com\/fc<\/a>!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I&#8217;ve always enjoyed playing with meme image creation tools such as saysit.com and many others. When I couldn&#8217;t find a creation tool to make fake fortune cookie images I decided to build my own. It would also give me a chance to play with some HTML5 technology I&#8217;ve been looking at, specifically SVG images. The [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3],"tags":[],"class_list":["post-243","post","type-post","status-publish","format-standard","hentry","category-web-development"],"_links":{"self":[{"href":"https:\/\/jimblackler.com\/index.php?rest_route=\/wp\/v2\/posts\/243","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/jimblackler.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/jimblackler.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/jimblackler.com\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/jimblackler.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=243"}],"version-history":[{"count":13,"href":"https:\/\/jimblackler.com\/index.php?rest_route=\/wp\/v2\/posts\/243\/revisions"}],"predecessor-version":[{"id":257,"href":"https:\/\/jimblackler.com\/index.php?rest_route=\/wp\/v2\/posts\/243\/revisions\/257"}],"wp:attachment":[{"href":"https:\/\/jimblackler.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=243"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/jimblackler.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=243"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/jimblackler.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=243"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}