diff --git a/src/Plugin/Field/FieldFormatter/TextimageTextFieldFormatter.php b/src/Plugin/Field/FieldFormatter/TextimageTextFieldFormatter.php
index 9caefcf..d459f86 100644
--- a/src/Plugin/Field/FieldFormatter/TextimageTextFieldFormatter.php
+++ b/src/Plugin/Field/FieldFormatter/TextimageTextFieldFormatter.php
@@ -277,7 +277,7 @@ class TextimageTextFieldFormatter extends FormatterBase implements ContainerFact
     $field = $instance->getFieldStorageDefinition();
     $token_data = [$instance->getTargetEntityTypeId() => $items->getEntity()];
 
-    // Get sanitized text strings from the text field.
+    // Get text strings from the text field.
     $text = $this->textimageFactory->getTextFieldText($items);
 
     // Get alt and title text from the formatter settings, and resolve tokens.
diff --git a/src/Tests/TextimageApiTest.php b/src/Tests/TextimageApiTest.php
index 18e6fa5..6a54de8 100644
--- a/src/Tests/TextimageApiTest.php
+++ b/src/Tests/TextimageApiTest.php
@@ -216,6 +216,50 @@ 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' => [
+          'strip_tags' => TRUE,
+          'decode_entities' => TRUE,
+          '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());
+    $effects = [];
+    $effects[] = [
+      'id' => 'image_effects_text_overlay',
+      'data' => [
+        'text' => [
+          'strip_tags' => TRUE,
+          'decode_entities' => TRUE,
+          'case_format' => '',
+          'maximum_chars' => NULL,
+        ],
+        'text_string' => 'Test preview',
+      ],
+    ];
+    $textimage = $this->textimageFactory->get();
+    $textimage
+      ->setEffects($effects)
+      ->process('<p>Para1</p><!-- Comment --> Para2');
+    $this->assertEqual(['Para1 Para2'], $textimage->getText());
+    $textimage = $this->textimageFactory->get();
+    $textimage
+      ->setEffects($effects)
+      ->process('&quot;Title&quot; One &hellip;');
+    $this->assertEqual(['"Title" One …'], $textimage->getText());
   }
 
   /**
diff --git a/src/Tests/TextimageFieldFormatterTest.php b/src/Tests/TextimageFieldFormatterTest.php
index 6687dd1..4b960ab 100644
--- a/src/Tests/TextimageFieldFormatterTest.php
+++ b/src/Tests/TextimageFieldFormatterTest.php
@@ -36,6 +36,7 @@ class TextimageFieldFormatterTest extends TextimageTestBase {
 
     // Create a new node.
     $field_value = $this->randomMachineName(20);
+    //$field_value = '<p>Para1</p><!-- Comment --> Para2  &quot;Title&quot; One &hellip;';
     $nid = $this->createTextimageNode('text', $field_name, $field_value, 'article');
     $node = Node::load($nid);
 
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..c671947 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);
   }
 
   /**
@@ -531,8 +512,7 @@ class TextimageFactory implements TextimageFactoryInterface {
   public function getTextFieldText(FieldItemListInterface $items) {
     $text = [];
     foreach ($items as $item) {
-      $value = $item->getValue();
-      $text[] = !empty($value['value']) ? strip_tags($value['value']) : '';
+      $text[] = $item->getValue() ?: '';
     }
     return $text;
   }
diff --git a/src/TextimageFactoryInterface.php b/src/TextimageFactoryInterface.php
index f81fde6..d122c45 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);
 
@@ -126,9 +128,6 @@ interface TextimageFactoryInterface {
   /**
    * Retrieves text from a Text field.
    *
-   * Text gets sanitized for use within Textimage: HTML tags are
-   * stripped.
-   *
    * @param Drupal\Core\Field\FieldItemListInterface $items
    *   Field items.
    *
