title: Largest potential PNG size given certain dimensions
body: <p>I'm currently creating an HTML5 <code>canvas</code>-based drawing program. The user can draw an image, or several 'pages' of images, and save it to the cloud for quick retrieval later. This is for use on an interactive whiteboard; the teacher cannot always be certain that the IWB they plan the lesson on is the one they will use in that class, so I want to make the data accessible from anywhere.</p>
  
  <p>I am sending the canvas data to the server as data URIs via Ajax, storing the data on the file system and a reference to the file in a database. My problem is that I'm not sure how much space on the file system these images will eventually take up.</p>
  
  <p>The files are saved as PNGs with an alpha transparency layer, and are 1280x720px. Depending on what is drawn, the file size varies significantly, which I assume is because PNGs are compressed. Because of this, I'm having trouble calculating the maximum possible file size that such an image could be. Since I want to assume a worst-case scenario, I'll assume that the PNG compression does nothing to decrease the file size. Given that, would the maximum file size be:</p>
  
  <pre><code>1280 x 720 x colordepth
  </code></pre>
  
  <p>? If so, what value should <code>colordepth</code> be, given I am exporting the images using <code>canvas.toDataURL()</code>? Would it differ depending on browser implementations of <code>canvas</code>? I'm totally in the dark here.</p>
  
  <p>I know PNG compression doesn't do well with photo-style images, so I have been trying to create something not easily compressible (mainly soft, fairly random gradients). The largest I have been able to create was about 675KB, but I'm sure that is nowhere near the potential maximum size.</p>
  
  <p>So I either need to know what the maximum file size could be, or what kind of image would offer the least potential for compression in a PNG, so I can experiment better.</p>
  
  <p>I hope this makes sense.</p>
  
  <hr>
  
  <p>There are a few similar questions on SO:</p>
  
  <ul>
  <li><p><a href="https://stackoverflow.com/questions/11035715/how-to-determine-png-dimensions-based-on-file-size-limit">How to determine png dimensions based on file size limit?</a></p></li>
  <li><p><a href="https://stackoverflow.com/questions/19403940/what-is-the-maximum-dimensions-of-an-image-that-cant-be-greater-than-8000-bytes">What is the maximum dimensions of an image that can&#39;t be greater than 8000 bytes?</a></p></li>
  </ul>
  
  <p>but none seemed to answer my question. Do enlighten me if I have missed something.</p>
  
  <hr>
  
  <p><strong>UPDATE</strong></p>
  
  <p>I've given <a href="https://stackoverflow.com/a/20415800/766945">Ken Fyrstenberg's idea</a> a try, and the preliminary results are quite something. Storing the image as a serialized object results in a set of data <em>less than a quarter</em> the size of the equivalent dataURL string. And this is before I've even begun to optimize it. I highly recommend anyone in a similar situation gives this method a try.</p>
  
  <hr>
  
  <p><strong>ANOTHER UPDATE</strong></p>
  
  <p>When I first started this, I was using SVG. However, the more the user drew, the more <code>DOMElement</code>s had to be onscreen at once, and the slower the response time became (especially with > 1000 elements). I had assumed that doing it with canvas and storing each stroke in an array as the user made it, there would be a similar issue. 'Tis not so.</p>
  
  <p>I guess there is much less overhead in simply storing path data, as compared to keeping track of a DOM element and all its properties, position in the document and relation to other elements.</p>
  
  <p>Upshot is, no matter how many strokes I stick into the array, the redraw operation is always lightning fast. This in addition to the aforementioned reduction in size when storing the data for later use, and incredibly easy implementation of undo/redo. <em>Very</em> impressed with both Javascript and canvas right now.</p>