OSDN Git Service

Docs: Reducing image-download sizes doc for Performance section on DAC.
authorDavid Friedman <dmail@google.com>
Tue, 20 Sep 2016 00:19:52 +0000 (17:19 -0700)
committerDavid Friedman <dmail@google.com>
Thu, 29 Sep 2016 22:19:46 +0000 (15:19 -0700)
Bug: 31312783

Change-Id: Ie6f1f2b29a9eb18359802576b49a364e12863fe8

docs/html/topic/performance/images/beforeafterindexed.png [new file with mode: 0644]
docs/html/topic/performance/images/comparison.png [new file with mode: 0644]
docs/html/topic/performance/images/decisions.png [new file with mode: 0644]
docs/html/topic/performance/images/moarparrots.png [new file with mode: 0644]
docs/html/topic/performance/images/palette.png [new file with mode: 0644]
docs/html/topic/performance/images/parrot.png [new file with mode: 0644]
docs/html/topic/performance/images/vq.gif [new file with mode: 0644]
docs/html/topic/performance/network-xfer.jd [new file with mode: 0644]

diff --git a/docs/html/topic/performance/images/beforeafterindexed.png b/docs/html/topic/performance/images/beforeafterindexed.png
new file mode 100644 (file)
index 0000000..dc7762e
Binary files /dev/null and b/docs/html/topic/performance/images/beforeafterindexed.png differ
diff --git a/docs/html/topic/performance/images/comparison.png b/docs/html/topic/performance/images/comparison.png
new file mode 100644 (file)
index 0000000..18f204c
Binary files /dev/null and b/docs/html/topic/performance/images/comparison.png differ
diff --git a/docs/html/topic/performance/images/decisions.png b/docs/html/topic/performance/images/decisions.png
new file mode 100644 (file)
index 0000000..d4f21f8
Binary files /dev/null and b/docs/html/topic/performance/images/decisions.png differ
diff --git a/docs/html/topic/performance/images/moarparrots.png b/docs/html/topic/performance/images/moarparrots.png
new file mode 100644 (file)
index 0000000..ee10ec1
Binary files /dev/null and b/docs/html/topic/performance/images/moarparrots.png differ
diff --git a/docs/html/topic/performance/images/palette.png b/docs/html/topic/performance/images/palette.png
new file mode 100644 (file)
index 0000000..eb6be6b
Binary files /dev/null and b/docs/html/topic/performance/images/palette.png differ
diff --git a/docs/html/topic/performance/images/parrot.png b/docs/html/topic/performance/images/parrot.png
new file mode 100644 (file)
index 0000000..7a8b86a
Binary files /dev/null and b/docs/html/topic/performance/images/parrot.png differ
diff --git a/docs/html/topic/performance/images/vq.gif b/docs/html/topic/performance/images/vq.gif
new file mode 100644 (file)
index 0000000..cbf6a35
Binary files /dev/null and b/docs/html/topic/performance/images/vq.gif differ
diff --git a/docs/html/topic/performance/network-xfer.jd b/docs/html/topic/performance/network-xfer.jd
new file mode 100644 (file)
index 0000000..7fe5594
--- /dev/null
@@ -0,0 +1,374 @@
+page.title=Reducing Image Download Sizes
+page.metaDescription=Improve network performance by optimizing image size.
+
+meta.tags="performance"
+page.tags="performance"
+
+@jd:body
+
+<div id="qv-wrapper">
+<div id="qv">
+
+<h2>In this document</h2>
+    <ol>
+
+      <li>
+        <a href="#uif">Understanding Image Formats</a>
+        <ul>
+           <li><a href="#png">PNG</a></li>
+           <li><a href="#jpg">JPG</a></li>
+           <li><a href="#webp">WebP</a></li>
+        </ul>
+      </li>
+      <li>
+        <a href="#sf">Selecting a Format</a></li>
+      <li><a href="#doqv">Determining Optimal Quality Values</a>
+        <ul>
+           <li><a href="#sv">Scalar Values (JPG, WebP only)</a></li>
+           <li><a href="#butter">Butteraugli</a></li>
+        </ul>
+      </li>
+      <li><a href="#sizes">Serving Sizes</a></li>
+    </ol>
+  </div>
+</div>
+
+<p>
+Most download traffic consists of images. As a result, the smaller you can make
+your downloadable images, the better a network experience your app can provide
+for users. This page provides guidance on making image files smaller and more
+network-friendly.
+</p>
+
+<h2 id="uif">Understanding Image Formats</h2>
+
+<p>Android apps typically use images that are in one or more of the following file
+formats: PNG, JPG, and WebP. For each of these formats, there are steps you can
+take to reduce image sizes.
+</p>
+
+<h3 id="png">PNG</h3>
+
+<p>
+A key to making your PNG files smaller is reducing the number of unique
+colors used in each row of pixels that comprises the image. By using fewer
+colors, you improve the compression potential at all of the other stages of
+the pipeline.
+</p>
+
+<p>
+Reducing the number of unique colors makes a significant difference because PNG
+compression effectiveness is partly a function of the degree to which
+horizontally adjacent pixel colors vary. Thus, reducing the number of unique
+colors in each row of your PNG images can help in reducing their file sizes.
+</p>
+
+<p>
+When deciding whether to pursue this strategy, you should keep in mind that
+reducing the number of unique colors effectively amounts to applying a lossy
+encoding stage to the image. However, an encoding tool may not be a good
+judge of how bad a seemingly small error looks to the human eye. Therefore,
+you should perform this work manually in order to help ensure
+the right balance between efficient compression and acceptable image quality.
+</p>
+
+<p>
+There are two particularly useful approaches you can take: striving for indexed
+formats, and applying vector quantization.
+</p>
+
+
+<h4 id="strive">Strive for indexed formats</h4>
+
+<p>
+Any attempt at color reduction should start with trying to optimize your colors
+so that you can use the INDEXED format when exporting the image as a PNG. The
+INDEXED color mode works by choosing the best 256 colors to use, and replacing
+all pixel values with indices into that color palette. The result is a
+reduction from 16 million (potential) colors to only 256 colors: from 3 (without
+transparency) or 4 (with transparency) bytes per pixel to 1 byte per pixel.
+This change is a significant first-step file size reduction.
+</p>
+
+<p>
+Figure 1 shows shows an image and its indexed variant.
+</p>
+
+  <img src="{@docRoot}topic/performance/images/beforeafterindexed.png">
+  <p class="img-caption">
+Figure 1. An image before and after conversion to the INDEXED format.
+  </p>
+
+
+<p>
+Figure 2 shows the color palette for the image in Figure 1:
+</p>
+
+  <img src="{@docRoot}topic/performance/images/palette.png">
+  <p class="img-caption">
+Figure 2. The color palette for the image in Figure 1.
+  </p>
+
+<p>
+Representing your image as a paletted image goes a long way toward
+significantly improving the file size, so it's worth investigating if the
+majority of your images can be converted.
+</p>
+
+<p>
+Of course, not every image can be accurately represented with only 256 colors.
+Some images, for example, might need 257, 310, 512, or 912 colors to
+look correct. In such cases, vector quantization can also be helpful.
+</p>
+
+<h4 id="vq">Vector quantization</h4>
+
+<p>
+The process of creating an indexed image may be better described as vector
+quantization (VQ). VQ serves as a rounding process for multidimensional
+numbers.  In this process, all the colors in your image get grouped based upon
+their similarity. For a given group, all colors in that group are replaced by a
+single <em>center point</em> value, which minimizes error for colors in that
+cell (or "site" if you're using the Voronoi terminology). In Figure 3,
+the green dots represent input colors, and the red dots are the center points
+that replace the input colors. Each cell is bounded by blue lines.
+</p>
+
+  <img src="{@docRoot}topic/performance/images/vq.gif">
+  <p class="img-caption">
+Figure 3. Applying vector quantization to the colors in an image.
+</p>
+
+<p>
+The result of applying VQ to an image reduces the number of unique colors,
+replacing each group of colors with a single color that's "pretty close"
+in visual quality.
+</p>
+
+<p>
+This technique also allows you to define the maximum number of unique colors in
+your image. For example, Figure 4 shows the a parrot head in 16.7 million colors
+(24 bits per pixel, or bpp) alongside a version that only allows only
+16 (3 bpp) unique colors to be used.
+</p>
+
+  <img src="{@docRoot}topic/performance/images/parrot.png">
+  <p class="img-caption">
+Figure 4. Image before and after application of vector quantification.
+  </p>
+
+<p>
+Immediately, you can see that there's a loss of quality; most of the gradient
+colors have been replaced, imparting a banding effect to the image. This image
+needs more than 16 unique colors.
+</p>
+
+<p>
+Setting up a VQ step in your pipeline can help you get a better sense of the
+true number of unique colors that your image uses, and can help you reduce them
+significantly. There are a number of readily available tools that you can use
+to help you implement this technique.
+</p>
+
+<h3 id="jpg">JPG</h3>
+
+<p>
+If you are using JPG images, there are several small changes you can make that
+potentially provide significant file-size savings. These include:
+</p>
+
+<ul>
+   <li>
+Producing a smaller file size through different encoding methods (without
+impacting quality).
+   </li>
+
+   <li>
+Adjusting quality slightly in order to yield better compression.
+   </li>
+</ul>
+
+<p>Pursuing these strategies can often net you file-size reductions of up to
+25%.
+</p>
+
+<p>
+When choosing tools, remember that photo exporting tools can
+insert unnecessary metadata, such as GPS information, into your images. At
+a minimum, try to leverage existing tools to help strip out this information
+from your files.
+</p>
+
+<h3 id="webp">WebP</h3>
+
+<p>
+WebP is a newer image format supported from Android 4.2.1 (API level 17). This
+format provides superior lossless and lossy compression for images on the web.
+Using WebP, developers can create smaller, richer images. WebP lossless image
+files are, on average,
+<a href="https://developers.google.com/speed/webp/docs/webp_lossless_alpha_study#conclusions">
+26% smaller</a> than PNGs. These image files also support
+transparency (also known as alpha channel) at a cost of just
+<a href="https://developers.google.com/speed/webp/docs/webp_lossless_alpha_study#results">
+22% more</a> bytes.
+</p>
+
+<p>
+WebP lossy images are
+<a href="https://developers.google.com/speed/webp/docs/webp_study#experiment_1_webp_vs_jpeg_at_equal_ssim_index">
+25-34% smaller</a> than comparable JPG images at equivalent
+<a href="https://en.wikipedia.org/wiki/Structural_similarity">SSIM</a>
+quality indices. For cases when lossy RGB compression is acceptable, lossy
+WebP also supports transparency, typically producing file sizes 3 times smaller
+than PNG.
+</p>
+
+<p>
+For more information about WebP, visit the
+<a href="https://developers.google.com/speed/webp/">WebP site</a>.
+</p>
+
+<h2 id="sf">Selecting a Format</h2>
+
+<p>
+Different image formats are suitable for different types of images. JPG and PNG
+have very different compression processes, and they produce quite different
+results.
+</p>
+
+<p>
+The decision between PNG and JPG often comes down to the complexity of the
+image itself. Figure 5 shows two images that come out quite differently
+depending on which compression scheme the developer applies. The image on the
+left has many small details, and thus compresses more efficiently with JPG. The
+image on the right, with runs of the same color, compresses more efficiently
+with PNG.
+</p>
+
+  <img src="{@docRoot}topic/performance/images/comparison.png">
+  <p class="img-caption">
+Figure 5. Suitable cases for JPG vs. PNG
+  </p>
+
+
+<p>
+WebP as a format can support both lossy and lossless modes, making it an ideal
+replacement for both PNG and JPG. The only thing to keep in mind is that it
+only has native support on devices running Android 4.2.1 (API level 17) and
+higher. Fortunately, the large
+<a
+href="https://developer.android.com/about/dashboards/index.html#Platform">
+majority of devices</a> satisfy that requirement.
+</p>
+
+<p>
+Figure 6 provides a simple visualization to help you decide which compression
+scheme to use.
+</p>
+
+  <img src="{@docRoot}topic/performance/images/decisions.png">
+  <p class="img-caption">
+Figure 6. Deciding on a compression scheme
+  </p>
+
+<h2 id="doqv">Determining Optimal Quality Values</h2>
+
+<p>
+There are several techniques you can use to achieve the right balance between
+compression and image quality. One technique uses scalar values and therefore
+only works for JPG and WebP. The other technique takes advantage of the
+Butteraugli library, and is usable for all image formats.
+</p>
+
+<h3 id="sv">Scalar values (JPG and WebP only)</h3>
+
+<p>
+The power of JPG and WebP comes from the fact that you can use a scalar value
+to balance quality against file size. The trick is finding out what the correct
+quality value is for your image. Too low a quality level produces a small file
+at the cost of image quality. Too high a quality level increases file size
+without providing a noticeable benefit to the user.
+</p>
+
+<p>
+The most straightforward solution is to pick some non-maximum value, and use
+that value. However, be aware that the quality value affects every image
+differently. While a quality of 75%, for example, may look fine on most images,
+there may be some cases do not fare as well. You should make sure to test your
+chosen maximum value against a representative sample of images. Also, make
+sure to perform all of your tests against the original images, and not on
+compressed versions.
+</p>
+
+<p>
+For large media applications that upload and re-send millions of JPGs a day,
+hand-tuning for each asset is impractical. You might address this challenge by
+specifying several different quality levels, according to image category. For
+example, you might set 35% as the quality setting for thumbnails, since a
+smaller image hides more compression artifacts.
+</p>
+
+<h3 id="butter">Butteraugli</h4>
+
+<p>
+The Butteraugli project is a library to test an image's Psychovisual Error
+Threshold: the point at which a viewer starts to notice image degradation. In
+other words, this project attempts to quantify how distorted your compressed
+image is.
+</p>
+
+<p>
+Butteraugli allows you to define a goal for visual quality, and then run PNG,
+JPG, WebP lossy, and WebP lossless compressions. You can then choose the image
+that is the best balance of file size and Butteraugli level. Figure 7 shows an
+example of how Butteraugli was used to find the minimal JPG quality level
+before the visual distortion was high enough for a user could perceive a
+problem; the result is a roughly 65% reduction in file size.
+</p>
+
+  <img src="{@docRoot}topic/performance/images/moarparrots.png">
+  <p class="img-caption">
+Figure 7. An image before and after application of Butteraugli technology.
+  </p>
+
+<p>
+Butteraugli allows you to proceed based on either output or input. That is, you
+can look for the lowest quality setting before a user perceives noticeable
+distortion in the resulting image, or you can iteratively set image-distortion
+levels to learn their associated quality levels.
+</p>
+
+<h2 id="sizes">Serving Sizes</h2>
+
+<p>
+It is tempting to keep only a single resolution of an image on a server. When a
+device accesses the image, the server serves it at that one resolution and
+leaves downscaling to the device.
+</p>
+
+<p>
+This solution is convenient for the developer, but potentially painful for the
+user, because the solution forces the user to download much more data than they
+need.
+
+You should instead store multiple sizes of images, and serve the size that is
+most appropriate for a particular use case. For example, for a thumbnail,
+serving an actual thumbnail image instead of serving and downscaling a
+full-size version consumes much less network bandwidth
+</p>
+
+</p>
+This approach is good for download speed, and is less costly for users who may
+be using limited or metered data plans. Proceeding like this also results in
+the image's taking less space on the device and in main memory. In the
+case of large images, such as 4K ones, this approach also saves the device
+from having to resize images before loading them.
+</p>
+
+<p>
+Implementing this approach requires that you have a backend image service to
+provide images at various resolutions with proper caching. There are existing
+services that can provide help with this task. For example,
+<a href="https://cloud.google.com/appengine/">App Engine</a> comes
+with image resizing functionality already installed.
+</p>