Rewrite the start of the Writing section to use from_array

GitOrigin-RevId: 5f0b4260815f40cc9e13ed1d51477048e9c7f75f
Change-Id: Ide05f7116ed913fef92b8a7f1f7ec317b0397d5e
diff --git a/man/ex.rst b/man/ex.rst
index f833aaf..e0d8b04 100644
--- a/man/ex.rst
+++ b/man/ex.rst
@@ -12,73 +12,90 @@
 Writing
 -------
 
-The basic strategy is to create a `~png.Writer` object (an instance of
-`png.Writer`) and then call its `~png.Writer.write` method
-with a binary file (that is open for writing), and the pixel data.
+The simplest way to write a PNG is to make a 2D array, pass it
+to `png.from_array` and save it::
+
+  import png
+
+  rows = [
+      [0, 1, 1, 1, 1, 1, 1, 0],
+      [1, 0, 0, 0, 0, 0, 0, 1],
+      [1, 0, 1, 0, 0, 1, 0, 1],
+      [1, 0, 0, 0, 0, 0, 0, 1],
+      [1, 0, 1, 0, 0, 1, 0, 1],
+      [1, 0, 0, 1, 1, 0, 0, 1],
+      [1, 0, 0, 0, 0, 0, 0, 1],
+      [0, 1, 1, 1, 1, 1, 1, 0],
+  ]
+  image = png.from_array(rows, "L;1")
+  image.save("smile.png")
+
+Python doesn't really have 2D arrays, so here i use a list of
+lists.
+Those who are already objecting that this isn't space efficient
+should be reassured that it is possible to use an
+`array.array
+<https://docs.python.org/3/library/array.html#array.array>`_
+which saves space horizontally, and it is also possible to
+stream using an iterator which saves space vertically.
+
+The ``"L;1"`` argument to `~png.from_array` is the *mode*.
+``"L"`` makes a greyscale image, one that has only *lightness*.
+The ``";1"`` sets the *bitdepth*.
+The bitdepth can be anywhere from 1 (with a maximum channel
+value of 1) to 16 (with a maximum channel value of 65,535).
+
+The default bitdepth is 8, which has a maximum channel value of 255.
+
+You can write colour RGB images with a mode of "RGB", and you
+can add an alpha channel to either mode to get "LA" or "RGBA".
+
+Writer objects
+^^^^^^^^^^^^^^
+
+`png.from_array` is in some ways a simplification.
+It uses a `png.Writer` object and you can use that too.
+While the `png.Writer` interface is currently more flexible (you
+can write extra chunks for example), it is also more
+complicated.
+
+The basic strategy is to create a `~png.Writer` object and then call its `~png.Writer.write` method
+with an open binary (writable) file, and the row data.
 The `~png.Writer` object
 encapsulates all the information about the PNG file: image size, colour,
 bit depth, and so on.
 
-A Ramp
-^^^^^^
-
-Create a one row image, that has all grey values from 0 to 255.  This is
-a bit like Netpbm's ``pgmramp``. ::
-
-  import png
-  f = open('ramp.png', 'wb')      # binary mode is important
-  w = png.Writer(256, 1, greyscale=True)
-  w.write(f, [range(256)])
-  f.close()
-
-Note that our single row, generated by ``range(256)``, must itself be
-enclosed in a list.  That's because the :meth:`~png.Writer.write` method expects
-a list of rows.
-
-
-A Little Message
-^^^^^^^^^^^^^^^^
-
-A list of strings holds a graphic in ASCII graphic form.  We convert it
-to a list of integer lists (the required form for the
-:meth:`~png.Writer.write` method),
-and write it out as a black-and-white PNG (bilevel greyscale). ::
-
-  import png
-  s = ['110010010011',
-       '101011010100',
-       '110010110101',
-       '100010010011']
-  s = [[int(c) for c in row] for row in s]
-
-  w = png.Writer(len(s[0]), len(s), greyscale=True, bitdepth=1)
-  f = open('png.png', 'wb')
-  w.write(f, s)
-  f.close()
-
-Note how we use ``len(s[0])`` (the length of the first row) for the *x*
-argument and ``len(s)`` (the number of rows) for the *y* argument.
-
 
 A Palette
 ^^^^^^^^^
 
-The previous example, "a little message", can be converted to colour
-simply by creating a PNG file with a palette.  The only difference is
-that a *palette* argument is passed to the :meth:`~png.Writer.write` method instead of
-``greyscale=True``::
+The previous example, a black-and-white smiley face, can
+be converted to colour
+by creating a PNG file with a palette.
+
+`~png.from_array` can't currently create a PNG file with a
+palette.
+But `~png.Writer` can,
+by passing a *palette* argument to the :meth:`~png.Writer.write`
+method::
 
   import png
-  s = ['110010010011',
-       '101011010100',
-       '110010110101',
-       '100010010011']
-  s = [[int(c) for c in row] for row in s]
 
-  palette=[(0x55,0x55,0x55), (0xff,0x99,0x99)]
-  w = png.Writer(len(s[0]), len(s), palette=palette, bitdepth=1)
-  f = open('png.png', 'wb')
-  w.write(f, s)
+  rows = [
+      [0, 1, 1, 1, 1, 1, 1, 0],
+      [1, 0, 0, 0, 0, 0, 0, 1],
+      [1, 0, 1, 0, 0, 1, 0, 1],
+      [1, 0, 0, 0, 0, 0, 0, 1],
+      [1, 0, 1, 0, 0, 1, 0, 1],
+      [1, 0, 0, 1, 1, 0, 0, 1],
+      [1, 0, 0, 0, 0, 0, 0, 1],
+      [0, 1, 1, 1, 1, 1, 1, 0],
+  ]
+
+  palette = [(0x55, 0x55, 0x55), (0xFF, 0x99, 0x99)]
+  w = png.Writer(size=(8, 8), palette=palette, bitdepth=1)
+  f = open("pal.png", "wb")
+  w.write(f, rows)
 
 Note that the palette consists of two entries (the bit depth is 1 so
 there are only 2 possible colours).  Each entry is an RGB triple.  If we