diff --git a/config/vufind/config.ini b/config/vufind/config.ini
index c23260d7a5becc694f8ebc45dbb01b5e4c52ab84..dd0eebe0be9d9c91534916b4df83714df221edb9 100644
--- a/config/vufind/config.ini
+++ b/config/vufind/config.ini
@@ -613,8 +613,9 @@ coverimagesCache = true
 
 ; These settings control the image to display when no book cover is available.
 ; If makeDynamicCovers is not false and the GD library is installed, VuFind will draw
-; cover images on the fly. Possible values: false, solid, grid. See [DynamicCovers]
-; below for more settings.
+; cover images on the fly. See [DynamicCovers] below for more settings. If set to
+; a non-Boolean value, for legacy reasons, the makeDynamicCovers setting will
+; be used as the backgroundMode setting of [DynamicCovers] if that setting is unset.
 ;makeDynamicCovers = true
 
 ; Otherwise, you can use noCoverAvailableImage to specify a
@@ -667,19 +668,33 @@ authors         = Wikipedia
 ; This section controls the behavior of the cover generator when makeDynamicCovers
 ; above is non-false.
 [DynamicCovers]
+; This controls the background layer of the generated image; options:
+; - solid: display a solid color
+; - grid: display a symmetrical random pattern seeded by title/callnumber
+;backgroundMode = grid
+
+; This controls the text layer of the generated image; options:
+; - default: display a title at the top and an author at the bottom
+; - initial: display only the first letter of the title as a stylized initial
+;textMode = default
+
 ; Font files specified here should exist in the css/font subdirectory of a theme.
 ; Some options are available by default inside the root theme.
 ;authorFont = "Roboto-Light.ttf"
 ;titleFont = "RobotoCondensed-Bold.ttf"
 
-; Covers are generated using title and author name; VuFind will try to display
-; everything by doing the following: break the title into lines, and if the title
-; is too long (more than maxTitleLines lines), it will display ellipses at the last
-; line.
+; In 'default' textMode, covers are generated using title and author name; VuFind
+; will try to display everything by doing the following: break the title into
+; lines, and if the title is too long (more than maxTitleLines lines), it will
+; display ellipses at the last line.
+;
 ; All text will be drawn using the specified textAlign alignment value using the
 ; relevant titleFontSize or authorFontSize setting, except that author names will
 ; be reduced to the minAuthorFontSize option if needed, and if that doesn't make
 ; it fit, text will be aligned left and truncated.
+;
+; When using 'initial' textMode, maxTitleLines and author-related settings are
+; ignored as they do not apply.
 ;textAlign = center
 ;titleFontSize = 9
 ;authorFontSize = 8
@@ -693,12 +708,12 @@ authors         = Wikipedia
 ; - authorFillColor,titleFillColor: the main color used
 ; - authorBorderColor,titleBorderColor: the color used to make a border; "none" is
 ;   a legal option in addition to colors.
-; - baseColor: When using grid covers, you may also choose a base color drawn
+; - baseColor: When using grid backgrounds, you may also choose a base color drawn
 ;   beneath the grid. Default is white.
-; - accentColor: When using solid covers, this is the background color; when using
-;   grid covers, this is the color of the grid pattern beneath the text. You may
-;   set this to "random" to select a random color seeded with text from the cover
-;   and adjusted with the "lightness" and "saturation" settings below.
+; - accentColor: When using solid backgrounds, this is the background color; when
+;   using grid backgrounds, this is the color of the grid pattern beneath the text.
+;   You may set this to "random" to select a random color seeded with text from
+;   the cover and adjusted with the "lightness" and "saturation" settings below.
 ;titleFillColor = black
 ;titleBorderColor = none
 ;authorFillColor = white
diff --git a/module/VuFind/src/VuFind/Cover/Generator.php b/module/VuFind/src/VuFind/Cover/Generator.php
index da37a53cb8f16f5d4504116be3daabaa26299cf1..b34960dee482e3906ddc0633503d90cbfaa104c0 100644
--- a/module/VuFind/src/VuFind/Cover/Generator.php
+++ b/module/VuFind/src/VuFind/Cover/Generator.php
@@ -111,7 +111,8 @@ class Generator
     {
         $this->themeTools = $themeTools;
         $default = [
-            'mode'         => 'grid',
+            'backgroundMode' => 'grid',
+            'textMode' => 'default',
             'authorFont'   => 'DroidSerif-Bold.ttf',
             'titleFontSize' => 7,
             'authorFontSize' => 6,
@@ -265,19 +266,108 @@ class Generator
      */
     public function generate($title, $author, $callnumber = null)
     {
-        switch (strtolower($this->settings->mode)) {
-        case 'solid':
-            $this->generateSolid($title, $author, $callnumber);
-        case 'grid':
-        default:
-            $this->generateGrid($title, $author, $callnumber);
-        }
+        // Generate seed from callnumber, title back up
+        $seed = $this->createSeed($title, $callnumber);
+
+        // Build the image
+        $this->drawBackgroundLayer($seed);
+        $this->drawTextLayer($title, $author);
 
+        // Render the image
         $png = $this->renderPng();
         $this->destroyImage();
         return $png;
     }
 
+    /**
+     * Draw the background behind the text.
+     *
+     * @param int $seed Seed value
+     *
+     * @return void
+     */
+    protected function drawBackgroundLayer($seed)
+    {
+        // Construct a method name using the mode setting; if the method is not
+        // defined, use the default drawGridBackground().
+        $mode = ucwords(strtolower($this->settings->backgroundMode));
+        $method = "draw{$mode}Background";
+        return method_exists($this, $method)
+            ? $this->$method($seed) : $this->drawGridBackground($seed);
+    }
+
+    /**
+     * Position the text on the image.
+     *
+     * @param string $title  Title of the book
+     * @param string $author Author of the book
+     *
+     * @return void
+     */
+    protected function drawTextLayer($title, $author)
+    {
+        // Construct a method name using the mode setting; if the method is not
+        // defined, use the default drawGridBackground().
+        $mode = ucwords(strtolower($this->settings->textMode));
+        $method = "draw{$mode}Text";
+        return method_exists($this, $method)
+            ? $this->$method($title, $author)
+            : $this->drawDefaultText($title, $author);
+    }
+
+    /**
+     * Position the text on the image using default rules.
+     *
+     * @param string $title  Title of the book
+     * @param string $author Author of the book
+     *
+     * @return void
+     */
+    protected function drawDefaultText($title, $author)
+    {
+        if (null !== $title) {
+            $this->drawTitle($title, $this->height / 8);
+        }
+        if (null !== $author) {
+            $this->drawAuthor($author);
+        }
+    }
+
+    /**
+     * Position the text on the image using "initials" rules.
+     *
+     * @param string $title  Title of the book
+     * @param string $author Author of the book
+     *
+     * @return void
+     */
+    protected function drawInitialText($title, $author)
+    {
+        // Get the first letter of title or author...
+        $initial = mb_substr($title . $author, 0, 1, 'UTF-8');
+
+        // Get the height of a character with no descenders:
+        $heightWithoutDescenders = $this->textHeight(
+            'O', $this->settings->titleFont, $this->settings->titleFontSize
+        );
+
+        // Get the height of the currently selected character:
+        $textHeight = $this->textHeight(
+            $initial, $this->settings->titleFont, $this->settings->titleFontSize
+        );
+
+        // Draw the letter...
+        $this->drawText(
+            $initial,
+            $heightWithoutDescenders + ($this->height - $textHeight) / 2,
+            $this->settings->titleFont,
+            $this->settings->titleFontSize,
+            $this->titleFillColor,
+            $this->titleBorderColor,
+            $this->settings->textAlign
+        );
+    }
+
     /**
      * Generate an accent color from a seed value.
      *
@@ -301,17 +391,12 @@ class Generator
     /**
      * Generates a solid color background, ala Google
      *
-     * @param string $title      Title of the book
-     * @param string $author     Author of the book
-     * @param string $callnumber Callnumber of the book
+     * @param int $seed Seed value
      *
      * @return void
      */
-    protected function generateSolid($title, $author, $callnumber)
+    protected function drawSolidBackground($seed)
     {
-        // Generate seed from callnumber, title back up
-        $seed = $this->createSeed($title, $callnumber);
-
         // Fill solid color
         imagefilledrectangle(
             $this->im,
@@ -321,34 +406,19 @@ class Generator
             $this->height,
             $this->getAccentColor($seed)
         );
-
-        $this->drawTitle($title, $this->height / 8);
-        $this->drawAuthor($author);
     }
 
     /**
      * Generates a grid of colors as primary feature
      *
-     * @param string $title      Title of the book
-     * @param string $author     Author of the book
-     * @param string $callnumber Callnumber of the book
+     * @param int $seed Seed value
      *
      * @return void
      */
-    protected function generateGrid($title, $author, $callnumber)
+    protected function drawGridBackground($seed)
     {
-        // Generate seed from callnumber, title back up
-        $seed = $this->createSeed($title, $callnumber);
         // Render the grid
-        $pattern = $this->createPattern($seed);
-        $this->render($pattern, $this->getAccentColor($seed));
-
-        if (null !== $title) {
-            $this->drawTitle($title, $this->height / 8);
-        }
-        if (null !== $author) {
-            $this->drawAuthor($author);
-        }
+        $this->renderGrid($this->createPattern($seed), $this->getAccentColor($seed));
     }
 
     /**
@@ -533,7 +603,7 @@ class Generator
      * @param string $font Full font path
      * @param string $size Size of the font
      *
-     * @return string file path
+     * @return int
      */
     protected function textWidth($text, $font, $size)
     {
@@ -541,16 +611,31 @@ class Generator
         return $p[2] - $p[0];
     }
 
+    /**
+     * Returns the height a string would render to
+     *
+     * @param string $text Text to test
+     * @param string $font Full font path
+     * @param string $size Size of the font
+     *
+     * @return int
+     */
+    protected function textHeight($text, $font, $size)
+    {
+        $p = imagettfbbox($size, 0, $font, $text);
+        return $p[1] - $p[5];
+    }
+
     /**
      * Simulate outlined text
      *
-     * @param string  $text     Text to render
-     * @param int     $y        Top position
-     * @param string  $font     Full path to font
-     * @param int     $fontSize Size of the font
-     * @param GCColor $mcolor   Main text color
-     * @param GCColor $scolor   Secondary border color
-     * @param string  $align    'left','center','right'
+     * @param string $text     Text to render
+     * @param int    $y        Top position
+     * @param string $font     Full path to font
+     * @param int    $fontSize Size of the font
+     * @param int    $mcolor   Main text color
+     * @param int    $scolor   Secondary border color
+     * @param string $align    'left','center','right'
      *
      * @return void
      */
@@ -606,12 +691,12 @@ class Generator
      * Convert 16 long binary string to 8x8 color grid
      * Reflects vertically and horizontally
      *
-     * @param string  $bc    Binary string of pattern
-     * @param GCColor $color Fill color
+     * @param string $bc    Binary string of pattern
+     * @param int    $color Fill color
      *
      * @return void
      */
-    protected function render($bc, $color)
+    protected function renderGrid($bc, $color)
     {
         $halfWidth = $this->width / 2;
         $halfHeight = $this->height / 2;
@@ -648,7 +733,7 @@ class Generator
      * @param int $s Saturation (0-255)
      * @param int $v Lightness (0-255)
      *
-     * @return GCColor
+     * @return int
      */
     protected function makeHSBColor($h, $s, $v)
     {
diff --git a/module/VuFind/src/VuFind/Cover/Loader.php b/module/VuFind/src/VuFind/Cover/Loader.php
index 844181e2849c5b0c7b56d57e1c578e14a15db4d3..a22682899556706d12935a850bbeff4355602ede 100644
--- a/module/VuFind/src/VuFind/Cover/Loader.php
+++ b/module/VuFind/src/VuFind/Cover/Loader.php
@@ -158,8 +158,11 @@ class Loader extends \VuFind\ImageLoader
     {
         $settings = isset($this->config->DynamicCovers)
             ? $this->config->DynamicCovers->toArray() : [];
-        $settings['mode'] = isset($this->config->Content->makeDynamicCovers)
-            ? $this->config->Content->makeDynamicCovers : false;
+        if (!isset($settings['backgroundMode'])
+            && isset($this->config->Content->makeDynamicCovers)
+        ) {
+            $settings['backgroundMode'] = $this->config->Content->makeDynamicCovers;
+        }
         return new \VuFind\Cover\Generator($this->themeTools, $settings);
     }