diff --git a/core/modules/file/tests/file_test/src/StreamWrapper/DummyRemoteStreamWrapper.php b/core/modules/file/tests/file_test/src/StreamWrapper/DummyRemoteStreamWrapper.php
index 12019e6..7f8cb5c 100644
--- a/core/modules/file/tests/file_test/src/StreamWrapper/DummyRemoteStreamWrapper.php
+++ b/core/modules/file/tests/file_test/src/StreamWrapper/DummyRemoteStreamWrapper.php
@@ -3,6 +3,7 @@
 namespace Drupal\file_test\StreamWrapper;
 
 use Drupal\Core\StreamWrapper\PublicStream;
+use Drupal\Core\StreamWrapper\StreamWrapperInterface;
 
 /**
  * Helper class for testing the stream wrapper registry.
@@ -16,6 +17,13 @@ class DummyRemoteStreamWrapper extends PublicStream {
   /**
    * {@inheritdoc}
    */
+  public static function getType() {
+    return StreamWrapperInterface::READ_VISIBLE;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
   public function getName() {
     return t('Dummy files (remote)');
   }
diff --git a/core/modules/image/tests/src/Kernel/ImageStyleCustomStreamWrappersTest.php b/core/modules/image/tests/src/Kernel/ImageStyleCustomStreamWrappersTest.php
new file mode 100644
index 0000000..7435dd8
--- /dev/null
+++ b/core/modules/image/tests/src/Kernel/ImageStyleCustomStreamWrappersTest.php
@@ -0,0 +1,124 @@
+<?php
+
+namespace Drupal\Tests\image\Kernel;
+
+use Drupal\Core\DependencyInjection\ContainerBuilder;
+use Drupal\Core\StreamWrapper\PrivateStream;
+use Drupal\Core\StreamWrapper\PublicStream;
+use Drupal\Core\StreamWrapper\StreamWrapperInterface;
+use Drupal\file_test\StreamWrapper\DummyReadOnlyStreamWrapper;
+use Drupal\file_test\StreamWrapper\DummyRemoteStreamWrapper;
+use Drupal\file_test\StreamWrapper\DummyStreamWrapper;
+use Drupal\image\Entity\ImageStyle;
+use Drupal\KernelTests\KernelTestBase;
+
+/**
+ * Tests derivative generation with source images using stream wrappers.
+ *
+ * @group image
+ */
+class ImageStyleCustomStreamWrappersTest extends KernelTestBase {
+
+  /**
+   * Modules to enable.
+   *
+   * @var string[]
+   */
+  public static $modules = ['system', 'image'];
+
+  /**
+   * A testing image style entity.
+   *
+   * @var \Drupal\image\ImageStyleInterface
+   */
+  protected $imageStyle;
+
+  /**
+   * The file system service.
+   *
+   * @var \Drupal\Core\File\FileSystemInterface
+   */
+  protected $fileSystem;
+
+  /**
+   * The stream wrapper manager.
+   *
+   * @var \Drupal\Core\StreamWrapper\StreamWrapperManagerInterface
+   */
+  protected $streamWrapperManager;
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+    $this->streamWrapperManager = $this->container->get('stream_wrapper_manager');
+    $this->fileSystem = $this->container->get('file_system');
+    $this->config('system.file')->set('default_scheme', 'public')->save();
+    $this->imageStyle = ImageStyle::create(['name' => 'test']);
+    $this->imageStyle->save();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function register(ContainerBuilder $container) {
+    parent::register($container);
+    foreach ($this->providerTestCustomStreamWrappers() as $stream_wrapper) {
+      $scheme = $stream_wrapper[0];
+      $class = $stream_wrapper[2];
+      $container->register("stream_wrapper.$scheme", $class)
+        ->addTag('stream_wrapper', ['scheme' => $scheme]);
+    }
+  }
+
+  /**
+   * Tests derivative creation with several source on a local writable stream.
+   *
+   * @dataProvider providerTestCustomStreamWrappers
+   *
+   * @param string $source_scheme
+   *   The source stream wrapper.
+   * @param string $target
+   *   The target part to be tested.
+   */
+  public function testCustomStreamWrappers($source_scheme, $target) {
+    $class = $this->streamWrapperManager->getClass($source_scheme);
+    $is_writable = $class::getType() & StreamWrapperInterface::WRITE;
+
+    // Compute the derivative uri scheme. Derivatives created from writable
+    // source stream wrappers will inherit the scheme from source. Derivatives
+    // created from read-only stream wrappers will have the default scheme.
+    $expected_scheme = $is_writable ? $source_scheme : $this->config('system.file')->get('default_scheme');
+
+    $derivative_uri = $this->imageStyle->buildUri("$source_scheme://$target");
+    $derivative_scheme = $this->fileSystem->uriScheme($derivative_uri);
+
+    // Check that the derivative scheme is the expected scheme.
+    $this->assertSame($expected_scheme, $derivative_scheme);
+
+    // Check that the derivative uri is the expected one.
+    $expected_uri = "$expected_scheme://styles/test/$source_scheme/$target";
+    $this->assertSame($expected_uri, $derivative_uri);
+  }
+
+  /**
+   * Provide test cases for testCustomStreamWrappers().
+   *
+   * @return array[]
+   *   An array having each element an array with threes items:
+   *   - The source stream wrapper.
+   *   - The target part to be tested.
+   *   - The stream wrapper service class.
+   */
+  public function providerTestCustomStreamWrappers() {
+    return [
+      ['public', 'image.png', PublicStream::class],
+      ['private', 'system/files/image.png', PrivateStream::class],
+      ['dummy', 'image.png', DummyStreamWrapper::class],
+      ['dummy-readonly', 'image.png', DummyReadOnlyStreamWrapper::class],
+      ['dummy-remote', 'image.png', DummyRemoteStreamWrapper::class],
+    ];
+  }
+
+}
