diff --git a/src/Tests/TextimageApiTest.php b/src/Tests/TextimageApiTest.php
index 18e6fa5..4ae3239 100644
--- a/src/Tests/TextimageApiTest.php
+++ b/src/Tests/TextimageApiTest.php
@@ -216,6 +216,25 @@ class TextimageApiTest extends TextimageTestBase {
     $this->assertEqual('image/png', $image->getMimeType());
     $image_file_extension = pathinfo($textimage->getUri(), PATHINFO_EXTENSION);
     $this->assertEqual('png', $image_file_extension);
+
+    // Check text altering via the effect's alter hook.
+    $effects = [];
+    $effects[] = [
+      'id' => 'image_effects_text_overlay',
+      'data' => [
+        'text' => [
+          'maximum_chars' => 12,
+          'excess_chars_text' => ' [more]',
+          'case_format' => 'upper',
+        ],
+        'text_string' => 'Test preview',
+      ],
+    ];
+    $textimage = $this->textimageFactory->get();
+    $textimage
+      ->setEffects($effects)
+      ->process('the quick brown fox jumps over the lazy dog');
+    $this->assertEqual(['THE QUICK BR [more]'], $textimage->getText());
   }
 
   /**
diff --git a/src/Textimage.php b/src/Textimage.php
index abb5a7c..dfb449b 100644
--- a/src/Textimage.php
+++ b/src/Textimage.php
@@ -520,14 +520,18 @@ class Textimage implements TextimageInterface {
     $this->tokenData['file'] = isset($this->tokenData['file']) ? $this->tokenData['file'] : $this->sourceImageFile;
     foreach ($default_text as $uuid => $default_text_item) {
       $text_item = array_shift($text);
+      $effect_instance = $this->imageEffectManager->createInstance($this->effects[$uuid]['id']);
+      $effect_instance->setConfiguration($this->effects[$uuid]);
       if ($text_item) {
         // Replace any tokens in text with run-time values.
         $text_item = ($text_item == '[textimage:default]') ? $default_text_item : $text_item;
-        $processed_text[$uuid] = $this->factory->processTextString($text_item, $this->effects[$uuid]['data']['text']['case_format'], $this->tokenData, $this->bubbleableMetadata);
+        $processed_text[$uuid] = $this->factory->processTextString($text_item, NULL, $this->tokenData, $this->bubbleableMetadata);
       }
       else {
-        $processed_text[$uuid] = $this->factory->processTextString($default_text_item, $this->effects[$uuid]['data']['text']['case_format'], $this->tokenData, $this->bubbleableMetadata);
+        $processed_text[$uuid] = $this->factory->processTextString($default_text_item, NULL, $this->tokenData, $this->bubbleableMetadata);
       }
+      // Let text be altered by the effect's alter hook.
+      $processed_text[$uuid] = $effect_instance->getAlteredText($processed_text[$uuid]);
     }
     $this->text = $processed_text;
 
diff --git a/src/TextimageFactory.php b/src/TextimageFactory.php
index d43ccfc..6cf7d22 100644
--- a/src/TextimageFactory.php
+++ b/src/TextimageFactory.php
@@ -122,26 +122,7 @@ class TextimageFactory implements TextimageFactoryInterface {
   public function processTextString($text, $case_format, array $token_data = [], BubbleableMetadata $bubbleable_metadata = NULL) {
     // Replace any tokens in text with run-time values.
     $token_data['user'] = !empty($token_data['user']) ? $token_data['user'] : $this->userStorage->load($this->currentUser->id());
-    $text = $this->token->replace($text, $token_data, [], $bubbleable_metadata);
-
-    // Convert case, if requested.
-    switch ($case_format) {
-      case 'upper':
-        return Unicode::strtoupper($text);
-
-      case 'lower':
-        return Unicode::strtolower($text);
-
-      case 'ucfirst':
-        return Unicode::ucfirst($text);
-
-      case 'ucwords':
-        return Unicode::ucwords($text);
-
-      default:
-        return $text;
-
-    }
+    return $this->token->replace($text, $token_data, [], $bubbleable_metadata);
   }
 
   /**
diff --git a/src/TextimageFactoryInterface.php b/src/TextimageFactoryInterface.php
index f81fde6..39b44b4 100644
--- a/src/TextimageFactoryInterface.php
+++ b/src/TextimageFactoryInterface.php
@@ -48,6 +48,8 @@ interface TextimageFactoryInterface {
    *
    * @return string
    *   The processed text string.
+   *
+   * @todo The $case_format parameter is deprecated, remove in a future major.
    */
   public function processTextString($text, $case_format, array $token_data = [], BubbleableMetadata $bubbleable_metadata = NULL);
 
