{"id":21462,"date":"2017-02-01T13:50:30","date_gmt":"2017-02-01T13:50:30","guid":{"rendered":"http:\/\/compressing_cellular_automata"},"modified":"2024-08-15T16:35:08","modified_gmt":"2024-08-15T23:35:08","slug":"compressing_cellular_automata","status":"publish","type":"post","link":"https:\/\/cloudinary.com\/blog\/compressing_cellular_automata","title":{"rendered":"Everything You Need to Know About Compressing Cellular Automata"},"content":{"rendered":"<div class=\"wp-block-cloudinary-markdown \"><script src=\"\/\/res.cloudinary.com\/cloudinary\/raw\/upload\/flif.js\"><\/script>\n<style>\ncanvas { max-width: 100%; margin: 3px auto; display: block;}\n<\/style>\n<p><a href=\"https:\/\/en.wikipedia.org\/wiki\/Cellular_automaton\">Cellular Automata<\/a> are pretty cool things to play with. There are many, many variants, like <a href=\"https:\/\/en.wikipedia.org\/wiki\/Conway%27s_Game_of_Life\">Conway\u2019s Game of Life<\/a>, <a href=\"https:\/\/en.wikipedia.org\/wiki\/Abelian_sandpile_model\">Abelian Sandpiles<\/a>, <a href=\"https:\/\/en.wikipedia.org\/wiki\/Langton%27s_loops\">Langton\u2019s Loops<\/a> and <a href=\"https:\/\/en.wikipedia.org\/wiki\/Brian%27s_Brain\">Brian\u2019s Brain<\/a>, but in this blogpost, I\u2019ll just talk about the simplest kinds of cellular automata: one-dimensional cellular automata.<\/p>\n<p>The simplest kind of 1D cellular automata are called <a href=\"https:\/\/en.wikipedia.org\/wiki\/Elementary_cellular_automaton\">Elementary Cellular Automata<\/a>. They work on a sequence of cells, which can each have two possible states: on and off, or 1 and 0. Starting from an initial sequence, the next sequence is computed based on simple rules: the next state of a cell only depends on the current state of the cell itself and its two neighbors.<\/p>\n<p>For example, here is an elementary cellular automaton called \u201cRule 22\u201d:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/cloudinary\/image\/upload\/rule_22.png\" alt=\"Rule 22\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"657\" height=\"187\"\/><\/p>\n<p>In this automaton, a cell is \u201con\u201d if in the previous generation, exactly one out of those three cells was on; otherwise it is \u201coff\u201d. Rules can be described using the <a href=\"https:\/\/en.wikipedia.org\/wiki\/Wolfram_code\">Wolfram code<\/a>, which was introduced by <a href=\"https:\/\/en.wikipedia.org\/wiki\/Stephen_Wolfram\">Stephen Wolfram<\/a>. In the case of elementary cellular automata, there are just 8 = 2<sup>3<\/sup> possible configurations of a given cell and its neighbors, and for each configuration there are just two options for the resulting new state, so there are 256 = 2<sup>8<\/sup> different elementary CAs, and they can be described using an 8-bit number. So the rules of the diagram above can be described with the binary number 00010110, or in decimal notation: 22.<\/p>\n<p>You can draw the evolution of a 1D cellular automaton (CA) as a 2D image, starting with some initial row of cells at the top and then drawing more and more generations in the rows below it. For rule 22, if you start with just a single black cell in the top row, you get the following image after 512 generations:<\/p>\n<p><canvas data-polyflif-src=\"https:\/\/res.cloudinary.com\/jon\/CA\/r22.flif\" width=\"1025\" height=\"512\"><\/canvas><\/p>\n<p>Interestingly, the resulting image looks a lot like a <a href=\"https:\/\/en.wikipedia.org\/wiki\/Sierpinski_triangle\">Sierpinski triangle<\/a>. In fact several of the elementary CAs look like this. It is one of the simplest examples of a <a href=\"https:\/\/en.wikipedia.org\/wiki\/Fractal\">fractal<\/a>: the image has a self-repeating structure at different scales.<\/p>\n<h2>Compressing CA images<\/h2>\n<p>You might expect that an image with so much repetitive structure in it, generated from such a simple rule, must compress very well. And it does. But it depends on the image format.<\/p>\n<p>As a <a href=\"https:\/\/res.cloudinary.com\/jon\/CA\/r22.jpg\" data-popup=\"true\">JPEG<\/a>, the above image doesn\u2019t compress very well: it weighs 79 KB at quality 90, and that is not even lossless. Even at the lowest possible quality, it is still 16 KB, and at that quality setting, the compression artifacts are quite bad:<\/p>\n<img decoding=\"async\" alt=\"JPEG Compressed\" src=\"https:\/\/res.cloudinary.com\/cloudinary\/image\/upload\/ca_jpeg_compressed.jpg\" style=\"margin: 0 auto;display: block\">\n<p>As a <a href=\"https:\/\/res.cloudinary.com\/jon\/CA\/r22.png\" data-popup=\"true\">PNG<\/a> however, the image is only 3.4 KB, and that is lossless. So <a href=\"https:\/\/cloudinary.com\/blog\/how_to_select_the_perfect_image_format\">picking the right format<\/a> can matter a lot, indeed. If you\u2019re using Cloudinary, you don\u2019t have to worry about that: just use <code>f_auto<\/code>, <code>q_auto<\/code> (<a href=\"https:\/\/cloudinary.com\/blog\/introducing_smart_cropping_intelligent_quality_selection_and_automated_responsive_images\">read more<\/a>) and you will automatically get the most suitable image format and quality settings \u2013 in this case, that would be a lossless PNG.<\/p>\n<p>In this example, PNG performs very well because there is a lot of exact repetition in the image. PNG is based on the <a href=\"https:\/\/en.wikipedia.org\/wiki\/DEFLATE\">DEFLATE<\/a> algorithm, which replaces such exact duplicates by backreferences, saving lots of bytes.<\/p>\n<p>However, not all cellular automata produce such easy-to-compress, repetitive patterns.<\/p>\n<h2>Rule 30<\/h2>\n<p>For example, Rule 30 produces the following image when starting from a single black cell:<\/p>\n<p><canvas data-polyflif-src=\"https:\/\/res.cloudinary.com\/jon\/CA\/r30.flif\" width=\"1025\" height=\"512\"><\/canvas><\/p>\n<p>This image weighs in at 215 KB as a quality 90 JPEG, and as a PNG, it is still 24 KB \u2013 compared to the 3.4 KB for the Sierpinski triangle image (Rule 22) of the same dimensions, that is quite a jump.<\/p>\n<p>The pattern that rule 30 creates is intriguing: on the left it is repetitive, but on the right, it gets much more chaotic. Triangular structures emerge, but they are positioned in seemingly random ways. Interestingly, in nature there seem to be processes that lead to similar patterns, like on the shell of this <em>Conus textile<\/em> sea snail:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/cloudinary\/image\/upload\/w_600\/sea_snail.jpg\" alt=\"Conus textile sea snail\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"600\" height=\"450\"\/><\/p>\n<p><em>(Image Copyright (c) 2005 Richard Ling, CC-BY-SA 3.0)<\/em><\/p>\n<h2>What if we could learn the rules?<\/h2>\n<p>PNG performs well for repetitive images like Rule 22, because it \u201csees\u201d the repetition and encodes it efficiently. It does not \u201csee\u201d the underlying rules of the cellular automaton though, so if those rules lead to chaotic emergent behavior, it gets into trouble. The same is true for GIF and lossless WebP, by the way.<\/p>\n<p>But what if I tell you that there is an image format that can essentially just \u201clearn the rules\u201d, and compress the image very well, regardless of what those rules actually lead to?<\/p>\n<p>Well, the MANIAC entropy coding of <a href=\"http:\/\/flif.info\/\">FLIF<\/a> can do just that. It can construct a MANIAC tree that exactly corresponds to the rules of an elementary CA, making sure that each of the 8 configurations of the rules correspond to a different context for the arithmetic coder. Then the probabilities in those contexts will rapidly converge to something very close to 0 or 1, and the encoded bits will have near-zero cost.<\/p>\n<p>For example, the Rule 22 image that was 3.4 KB as a PNG file, is just 83 bytes as a FLIF file. The Rule 30 image that was 24 KB as a PNG, is only 92 bytes as a FLIF.<\/p>\n<p>In fact, those two CA images above (if you have javascript enabled) are actually FLIF files, decoded in your browser using a javascript <a href=\"https:\/\/en.wikipedia.org\/wiki\/Polyfill\">polyfill<\/a> called <a href=\"https:\/\/github.com\/UprootLabs\/poly-flif\">PolyFLIF<\/a>.<\/p>\n<p>I obtained the smallest FLIF files with the following command-line options for the encoder:<\/p>\n<p><code>flif -NX1<\/code><\/p>\n<p>The option <code>-N<\/code> causes the encoder to use the non-interlaced variant of the format, so the encoding is top-to-bottom, just like the evolution of the automaton. The default is to do interlacing, which would mean that the encoder cannot \u201csee\u201d the structure since it is encoding pixels from all over the image, resulting in much worse compression. The option <code>-X1<\/code> is less important; it allows the arithmetic coder to use more extreme chances (1\/4096 instead of the default 2\/4096), bringing the \u201cnear-zero\u201d cost of the bits even closer to zero.<\/p>\n<h2>Larger and larger images<\/h2>\n<p>Here\u2019s an animated plot of the image file size of Rule 22 images with more and more rows, using different image compression formats. Note: the y-axis is logarithmic here!<\/p>\n<video controls poster=\"https:\/\/res.cloudinary.com\/cloudinary\/video\/upload\/w_770,so_0,q_auto,f_auto\/plot_rule22.png\">\n\t<source src=\"https:\/\/res.cloudinary.com\/cloudinary\/video\/upload\/plot_rule22.mp4\" type=\"video\/mp4\">\n\t<source src=\"https:\/\/res.cloudinary.com\/cloudinary\/video\/upload\/plot_rule22.webm\" type=\"video\/webm\">\n\t<source src=\"https:\/\/res.cloudinary.com\/cloudinary\/video\/upload\/plot_rule22.ogv\" type=\"video\/ogg\">\n\tPlot rule22\n<\/video>\n<p>If you want an even more extreme example, <a href=\"https:\/\/res.cloudinary.com\/jon\/r30-50MP.flif\" data-popup=\"true\">here is a FLIF file<\/a> that contains a 50 megapixel image of the Rule 30 evolution (5000 rows). Here are the file sizes for that particular image:<\/p>\n<p><span><span><br \/><\/span><\/span><\/p>\n<div style=\"margin-left: 0pt;\" dir=\"ltr\">\n<table style=\"border: none; border-collapse: collapse; width: 100%;\"><colgroup><col width=\"*\" \/><col width=\"*\" \/><\/colgroup>\n<tbody>\n<tr style=\"height: 0px;\">\n<td style=\"vertical-align: top; padding: 7px 7px 7px 7px; border: solid #000000 1px;\">\n<p style=\"line-height: 1.2; margin-top: 0pt; margin-bottom: 0pt;\" dir=\"ltr\"><span style=\"font-size: 14.6667px; font-family: Arial; background-color: transparent; vertical-align: baseline; white-space: pre-wrap;\">FLIF<\/span><\/p>\n<\/td>\n<td style=\"vertical-align: top; padding: 7px 7px 7px 7px; border: solid #000000 1px; text-align:right;\">\n<p style=\"line-height: 1.2; margin-top: 0pt; margin-bottom: 0pt;\" dir=\"ltr\"><span style=\"font-size: 14.6667px; font-family: Arial; background-color: transparent; vertical-align: baseline; white-space: pre-wrap;\">2,686 bytes<\/span><\/p>\n<\/td>\n<\/tr>\n<tr style=\"height: 0px;\">\n<td style=\"vertical-align: top; padding: 7px 7px 7px 7px; border: solid #000000 1px;\">\n<p style=\"line-height: 1.2; margin-top: 0pt; margin-bottom: 0pt;\" dir=\"ltr\"><span style=\"font-size: 14.6667px; font-family: Arial; background-color: transparent; vertical-align: baseline; white-space: pre-wrap;\">PNG<\/span><\/p>\n<\/td>\n<td style=\"vertical-align: top; padding: 7px 7px 7px 7px; border: solid #000000 1px; text-align:right;\">\n<p style=\"line-height: 1.2; margin-top: 0pt; margin-bottom: 0pt;\" dir=\"ltr\"><span style=\"font-size: 14.6667px; font-family: Arial; background-color: transparent; vertical-align: baseline; white-space: pre-wrap;\">2,001,971 bytes<\/span><\/p>\n<\/td>\n<\/tr>\n<tr style=\"height: 0px;\">\n<td style=\"vertical-align: top; padding: 7px 7px 7px 7px; border: solid #000000 1px;\">\n<p style=\"line-height: 1.2; margin-top: 0pt; margin-bottom: 0pt;\" dir=\"ltr\"><span style=\"font-size: 14.6667px; font-family: Arial; background-color: transparent; vertical-align: baseline; white-space: pre-wrap;\">Lossless WebP<\/span><\/p>\n<\/td>\n<td style=\"vertical-align: top; padding: 7px 7px 7px 7px; border: solid #000000 1px; text-align:right;\">\n<p style=\"line-height: 1.2; margin-top: 0pt; margin-bottom: 0pt;\" dir=\"ltr\"><span style=\"font-size: 14.6667px; font-family: Arial; background-color: transparent; vertical-align: baseline; white-space: pre-wrap;\">1,967,008 bytes<\/span><\/p>\n<\/td>\n<\/tr>\n<tr style=\"height: 0px;\">\n<td style=\"vertical-align: top; padding: 7px 7px 7px 7px; border: solid #000000 1px;\">\n<p style=\"line-height: 1.2; margin-top: 0pt; margin-bottom: 0pt;\" dir=\"ltr\"><span style=\"font-size: 14.6667px; font-family: Arial; background-color: transparent; vertical-align: baseline; white-space: pre-wrap;\">Lossy WebP, default quality<\/span><\/p>\n<\/td>\n<td style=\"vertical-align: top; padding: 7px 7px 7px 7px; border: solid #000000 1px; text-align:right;\">\n<p style=\"line-height: 1.2; margin-top: 0pt; margin-bottom: 0pt;\" dir=\"ltr\"><span style=\"font-size: 14.6667px; font-family: Arial; background-color: transparent; vertical-align: baseline; white-space: pre-wrap;\">14,240,092 bytes<\/span><\/p>\n<\/td>\n<\/tr>\n<tr style=\"height: 0px;\">\n<td style=\"vertical-align: top; padding: 7px 7px 7px 7px; border: solid #000000 1px;\">\n<p style=\"line-height: 1.2; margin-top: 0pt; margin-bottom: 0pt;\" dir=\"ltr\"><span style=\"font-size: 14.6667px; font-family: Arial; background-color: transparent; vertical-align: baseline; white-space: pre-wrap;\">Lossy WebP, lowest possible quality<\/span><\/p>\n<\/td>\n<td style=\"vertical-align: top; padding: 7px 7px 7px 7px; border: solid #000000 1px; text-align:right;\">\n<p style=\"line-height: 1.2; margin-top: 0pt; margin-bottom: 0pt;\" dir=\"ltr\"><span style=\"font-size: 14.6667px; font-family: Arial; background-color: transparent; vertical-align: baseline; white-space: pre-wrap;\">5,985,102 bytes<\/span><\/p>\n<\/td>\n<\/tr>\n<tr style=\"height: 0px;\">\n<td style=\"vertical-align: top; padding: 7px 7px 7px 7px; border: solid #000000 1px;\">\n<p style=\"line-height: 1.2; margin-top: 0pt; margin-bottom: 0pt;\" dir=\"ltr\"><span style=\"font-size: 14.6667px; font-family: Arial; background-color: transparent; vertical-align: baseline; white-space: pre-wrap;\">JPEG, quality 90<\/span><\/p>\n<\/td>\n<td style=\"vertical-align: top; padding: 7px 7px 7px 7px; border: solid #000000 1px; text-align:right;\">\n<p style=\"line-height: 1.2; margin-top: 0pt; margin-bottom: 0pt;\" dir=\"ltr\"><span style=\"font-size: 14.6667px; font-family: Arial; background-color: transparent; vertical-align: baseline; white-space: pre-wrap;\">20,300,915 bytes<\/span><\/p>\n<\/td>\n<\/tr>\n<tr style=\"height: 0px;\">\n<td style=\"vertical-align: top; padding: 7px 7px 7px 7px; border: solid #000000 1px;\">\n<p style=\"line-height: 1.2; margin-top: 0pt; margin-bottom: 0pt;\" dir=\"ltr\"><span style=\"font-size: 14.6667px; font-family: Arial; background-color: transparent; vertical-align: baseline; white-space: pre-wrap;\">JPEG, lowest possible quality<\/span><\/p>\n<\/td>\n<td style=\"vertical-align: top; padding: 7px 7px 7px 7px; border: solid #000000 1px; text-align:right;\">\n<p style=\"line-height: 1.2; margin-top: 0pt; margin-bottom: 0pt;\" dir=\"ltr\"><span style=\"font-size: 14.6667px; font-family: Arial; background-color: transparent; vertical-align: baseline; white-space: pre-wrap;\">4,243,508 bytes<\/span><\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<p style=\"line-height: 1.38; margin-top: 0pt; margin-bottom: 0pt;\" dir=\"ltr\">&nbsp;<\/p>\n<p>Amazing how poorly the lossy formats perform on this image, isn\u2019t it? Also rather interesting that PNG and lossless WebP are so close to one another \u2013 not that surprising if you know they\u2019re based on similar entropy coding methods, but still. For me however (being the author of FLIF), the nicest thing about the above table is that FLIF beats anything else by a few orders of magnitude :).<\/p>\n<p>Now, of course you shouldn\u2019t draw too many conclusions from something like this. This is an image that is very special in the sense that it represents a best-case scenario for FLIF, while it is quite close to a worst-case scenario for the other formats. It is not that hard to come up with images that turn the tables and compress exceptionally well with, say, PNG or WebP, but compress poorly in FLIF.<\/p>\n<h2>More complicated cellular automata<\/h2>\n<p>FLIF can learn all elementary cellular automata, but it can also handle some more complicated ones. For example, if you allow the next state of a cell to depend not just on the current state of the cell and its neighbors, but also on the <em>previous<\/em> state of the cell, you get a somewhat different kind of cellular automata that can produce images like these:<\/p>\n<p><canvas data-polyflif-src=\"https:\/\/res.cloudinary.com\/jon\/CA\/r_tt_25.flif\" width=\"500\" height=\"500\"><\/canvas>\n<canvas data-polyflif-src=\"https:\/\/res.cloudinary.com\/jon\/CA\/r_tt_218.flif\" width=\"500\" height=\"500\"><\/canvas><\/p>\n<p>Here, I initialized the top row randomly, so the FLIF files are somewhat larger: 269 bytes for the first image, 240 bytes for the second. The corresponding PNG files are 16 KB and 32 KB.<\/p>\n<h2>Totalistic Cellular Automata<\/h2>\n<p>There\u2019s no reason to use only two colors (or states). When using more states, it becomes a bit more tricky to describe the rules concisely, since the number of different automata grows quite quickly; with just 3 states, there are 7,625 billion (3<sup>27<\/sup>) automata if you only look at the cell and its two neighbors, and you would need a 27-digit ternary number to describe them.<\/p>\n<p>To simplify things, you can look at <a href=\"http:\/\/mathworld.wolfram.com\/TotalisticCellularAutomaton.html\">totalistic cellular automata<\/a>, which are a subset of that huge set. In a totalistic CA, the new state depends only on the <em>sum<\/em> of the current states that are being considered. This forces certain symmetries. For example, the configuration 0,2,1 must result in the same new state as the configuration 1,2,0, or the configuration 1,1,1 for that matter. As a result, you need way fewer digits to specify a totalistic CA. If you have three cell states, the sum can be anything between 0 and 6, and for each of those 7 configurations, there are 3 possible new states, so 7 ternary digits are enough and there are \u201conly\u201d 2187 totalistic 3-color automata.<\/p>\n<p>One of those is Rule 1599, which is my favorite totalistic CA. It looks like this:<\/p>\n<p><canvas data-polyflif-src=\"https:\/\/res.cloudinary.com\/jon\/CA\/r1599.flif\" width=\"300\" height=\"1000\"><\/canvas><\/p>\n<p>Starting from a single \u201c1\u201d cell, Rule 1599 produces this intricate pattern, which goes on for about 8000 rows and then it kind of stops, leaving only a trail of some repeating pattern, about 700 columns wide, that goes on forever. <a href=\"https:\/\/res.cloudinary.com\/jon\/CA\/r1599-full.flif\" data-popup=\"true\">Here is an 899-byte FLIF file<\/a> that encodes the entire interesting part \u2013 it\u2019s a 720&#215;9000 image, so I\u2019m not going to let your browser decode that here.<\/p>\n<p>Take a look at this animated plot of the file sizes:<\/p>\n<video controls poster=\"https:\/\/res.cloudinary.com\/cloudinary\/video\/upload\/w_770,so_0,q_auto,f_auto\/plot_rule1599.png\">\n\t<source src=\"https:\/\/res.cloudinary.com\/cloudinary\/video\/upload\/w_770\/plot_rule1599.mp4\" type=\"video\/mp4\">\n\t<source src=\"https:\/\/res.cloudinary.com\/cloudinary\/video\/upload\/w_770\/plot_rule1599.webm\" type=\"video\/webm\">\n\t<source src=\"https:\/\/res.cloudinary.com\/cloudinary\/video\/upload\/w_770\/plot_rule1599.ogv\" type=\"video\/ogg\">\n\tPlot rule1599\n<\/video>\n<p>In this plot, I restricted the number of MANIAC tree learning iterations to just one. You can see that initially the file size grows as the image grows, and it seems to take some time before FLIF \u201cfigures out\u201d the rules of the game completely. The file size actually drops while it is learning the rules, and then it very slowly starts to go up again, encoding the extra pixels at near-zero cost. At 3000 rows, the FLIF file is still only 667 bytes, while WebP and PNG are around 140 KB and the lossy JPEG is getting close to 1 MB.<\/p>\n<h2>Conclusion<\/h2>\n<p>One obvious conclusion from all this is <strong>don\u2019t use lossy compression on images of Cellular Automata<\/strong> or in general, on highly structured artificial images with lots of fine details. That\u2019s nothing new, but I think the examples above bring down this point quite nicely.<\/p>\n<p>What\u2019s hopefully new and interesting is that there can be huge differences between different lossless image compression formats. If the format is somehow capable of capturing the \u201cessence\u201d of the image, it might be able to compress it extremely well. For PNG (and lossless WebP), this \u201cbest case\u201d scenario is <em>exact repetition<\/em>. For FLIF, it is harder to describe what the \u201cbest cases\u201d are, but Cellular Automata certainly seem to be among them.<\/p>\n<p>Finally, if all went well, this blogpost is actually the first \u201creal\u201d webpage to use FLIF images for purposes other than to demonstrate the javascript polyfill. I hope you enjoyed it!<\/p>\n<\/div>","protected":false},"excerpt":{"rendered":"","protected":false},"author":41,"featured_media":21463,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_cloudinary_featured_overwrite":false,"footnotes":""},"categories":[1],"tags":[179,227,321],"class_list":["post-21462","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized","tag-jpeg","tag-performance-optimization","tag-webp"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v25.6 (Yoast SEO v26.9) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>How to compress cellular automata images<\/title>\n<meta name=\"description\" content=\"This blog post tackles cellular automata images and explores the best way to compress them (spoiler alert - it&#039;s FLIF!)\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/cloudinary.com\/blog\/compressing_cellular_automata\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Everything You Need to Know About Compressing Cellular Automata\" \/>\n<meta property=\"og:description\" content=\"This blog post tackles cellular automata images and explores the best way to compress them (spoiler alert - it&#039;s FLIF!)\" \/>\n<meta property=\"og:url\" content=\"https:\/\/cloudinary.com\/blog\/compressing_cellular_automata\" \/>\n<meta property=\"og:site_name\" content=\"Cloudinary Blog\" \/>\n<meta property=\"article:published_time\" content=\"2017-02-01T13:50:30+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2024-08-15T23:35:08+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/v1649724547\/Web_Assets\/blog\/cellular_automata\/cellular_automata-png?_i=AA\" \/>\n\t<meta property=\"og:image:width\" content=\"1540\" \/>\n\t<meta property=\"og:image:height\" content=\"802\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"NewsArticle\",\"@id\":\"https:\/\/cloudinary.com\/blog\/compressing_cellular_automata#article\",\"isPartOf\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/compressing_cellular_automata\"},\"author\":{\"name\":\"\",\"@id\":\"\"},\"headline\":\"Everything You Need to Know About Compressing Cellular Automata\",\"datePublished\":\"2017-02-01T13:50:30+00:00\",\"dateModified\":\"2024-08-15T23:35:08+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/compressing_cellular_automata\"},\"wordCount\":9,\"publisher\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/compressing_cellular_automata#primaryimage\"},\"thumbnailUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649724547\/Web_Assets\/blog\/cellular_automata\/cellular_automata.png?_i=AA\",\"keywords\":[\"JPEG\",\"Performance Optimization\",\"WebP\"],\"inLanguage\":\"en-US\",\"copyrightYear\":\"2017\",\"copyrightHolder\":{\"@id\":\"https:\/\/cloudinary.com\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/cloudinary.com\/blog\/compressing_cellular_automata\",\"url\":\"https:\/\/cloudinary.com\/blog\/compressing_cellular_automata\",\"name\":\"How to compress cellular automata images\",\"isPartOf\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/compressing_cellular_automata#primaryimage\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/compressing_cellular_automata#primaryimage\"},\"thumbnailUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649724547\/Web_Assets\/blog\/cellular_automata\/cellular_automata.png?_i=AA\",\"datePublished\":\"2017-02-01T13:50:30+00:00\",\"dateModified\":\"2024-08-15T23:35:08+00:00\",\"description\":\"This blog post tackles cellular automata images and explores the best way to compress them (spoiler alert - it's FLIF!)\",\"breadcrumb\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/compressing_cellular_automata#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/cloudinary.com\/blog\/compressing_cellular_automata\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/cloudinary.com\/blog\/compressing_cellular_automata#primaryimage\",\"url\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649724547\/Web_Assets\/blog\/cellular_automata\/cellular_automata.png?_i=AA\",\"contentUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649724547\/Web_Assets\/blog\/cellular_automata\/cellular_automata.png?_i=AA\",\"width\":1540,\"height\":802},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/cloudinary.com\/blog\/compressing_cellular_automata#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/cloudinary.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Everything You Need to Know About Compressing Cellular Automata\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#website\",\"url\":\"https:\/\/cloudinary.com\/blog\/\",\"name\":\"Cloudinary Blog\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/cloudinary.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#organization\",\"name\":\"Cloudinary Blog\",\"url\":\"https:\/\/cloudinary.com\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649718331\/Web_Assets\/blog\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA\",\"contentUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649718331\/Web_Assets\/blog\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA\",\"width\":312,\"height\":60,\"caption\":\"Cloudinary Blog\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#\/schema\/logo\/image\/\"}},{\"@type\":\"Person\",\"@id\":\"\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"How to compress cellular automata images","description":"This blog post tackles cellular automata images and explores the best way to compress them (spoiler alert - it's FLIF!)","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/cloudinary.com\/blog\/compressing_cellular_automata","og_locale":"en_US","og_type":"article","og_title":"Everything You Need to Know About Compressing Cellular Automata","og_description":"This blog post tackles cellular automata images and explores the best way to compress them (spoiler alert - it's FLIF!)","og_url":"https:\/\/cloudinary.com\/blog\/compressing_cellular_automata","og_site_name":"Cloudinary Blog","article_published_time":"2017-02-01T13:50:30+00:00","article_modified_time":"2024-08-15T23:35:08+00:00","og_image":[{"width":1540,"height":802,"url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/v1649724547\/Web_Assets\/blog\/cellular_automata\/cellular_automata-png?_i=AA","type":"image\/png"}],"twitter_card":"summary_large_image","schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"NewsArticle","@id":"https:\/\/cloudinary.com\/blog\/compressing_cellular_automata#article","isPartOf":{"@id":"https:\/\/cloudinary.com\/blog\/compressing_cellular_automata"},"author":{"name":"","@id":""},"headline":"Everything You Need to Know About Compressing Cellular Automata","datePublished":"2017-02-01T13:50:30+00:00","dateModified":"2024-08-15T23:35:08+00:00","mainEntityOfPage":{"@id":"https:\/\/cloudinary.com\/blog\/compressing_cellular_automata"},"wordCount":9,"publisher":{"@id":"https:\/\/cloudinary.com\/blog\/#organization"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/compressing_cellular_automata#primaryimage"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649724547\/Web_Assets\/blog\/cellular_automata\/cellular_automata.png?_i=AA","keywords":["JPEG","Performance Optimization","WebP"],"inLanguage":"en-US","copyrightYear":"2017","copyrightHolder":{"@id":"https:\/\/cloudinary.com\/#organization"}},{"@type":"WebPage","@id":"https:\/\/cloudinary.com\/blog\/compressing_cellular_automata","url":"https:\/\/cloudinary.com\/blog\/compressing_cellular_automata","name":"How to compress cellular automata images","isPartOf":{"@id":"https:\/\/cloudinary.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/cloudinary.com\/blog\/compressing_cellular_automata#primaryimage"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/compressing_cellular_automata#primaryimage"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649724547\/Web_Assets\/blog\/cellular_automata\/cellular_automata.png?_i=AA","datePublished":"2017-02-01T13:50:30+00:00","dateModified":"2024-08-15T23:35:08+00:00","description":"This blog post tackles cellular automata images and explores the best way to compress them (spoiler alert - it's FLIF!)","breadcrumb":{"@id":"https:\/\/cloudinary.com\/blog\/compressing_cellular_automata#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/cloudinary.com\/blog\/compressing_cellular_automata"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/cloudinary.com\/blog\/compressing_cellular_automata#primaryimage","url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649724547\/Web_Assets\/blog\/cellular_automata\/cellular_automata.png?_i=AA","contentUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649724547\/Web_Assets\/blog\/cellular_automata\/cellular_automata.png?_i=AA","width":1540,"height":802},{"@type":"BreadcrumbList","@id":"https:\/\/cloudinary.com\/blog\/compressing_cellular_automata#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/cloudinary.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Everything You Need to Know About Compressing Cellular Automata"}]},{"@type":"WebSite","@id":"https:\/\/cloudinary.com\/blog\/#website","url":"https:\/\/cloudinary.com\/blog\/","name":"Cloudinary Blog","description":"","publisher":{"@id":"https:\/\/cloudinary.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/cloudinary.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/cloudinary.com\/blog\/#organization","name":"Cloudinary Blog","url":"https:\/\/cloudinary.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/cloudinary.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649718331\/Web_Assets\/blog\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA","contentUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649718331\/Web_Assets\/blog\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA","width":312,"height":60,"caption":"Cloudinary Blog"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":""}]}},"jetpack_featured_media_url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649724547\/Web_Assets\/blog\/cellular_automata\/cellular_automata.png?_i=AA","_links":{"self":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/21462","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/users\/41"}],"replies":[{"embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/comments?post=21462"}],"version-history":[{"count":1,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/21462\/revisions"}],"predecessor-version":[{"id":35262,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/21462\/revisions\/35262"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/media\/21463"}],"wp:attachment":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/media?parent=21462"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/categories?post=21462"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/tags?post=21462"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}