We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Additional improvement for da.image.imread
I think following 2 improvements make the function better.
#### 1. Allow custom `imread` function.

Some prefer `opencv` which reads color in BGR order, otherwise `skimage` reads in RGB order. Adding `dialect` option (like `dialect='skimage'` or `dialect='cv'`) or accept different file read function may better.
#### 2. Allow custom preprocessing function.

In image processing, input images may have different sizes. In these case, preprocessing is needed between image read and array creation. This preprocessing function must return the same size of array on user's responsibility.


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `dask/array/image.py`
Content:
```
1 from glob import glob
2 import os
3 
4 try:
5     from skimage.io import imread as sk_imread
6 except ImportError:
7     pass
8 
9 from .core import Array
10 from ..base import tokenize
11 
12 def add_leading_dimension(x):
13     return x[None, ...]
14 
15 
16 def imread(filename):
17     """ Read a stack of images into a dask array
18 
19     Parameters
20     ----------
21 
22     filename: string
23         A globstring like 'myfile.*.png'
24 
25     Example
26     -------
27 
28     >>> from dask.array.image import imread
29     >>> im = imread('2015-*-*.png')  # doctest: +SKIP
30     >>> im.shape  # doctest: +SKIP
31     (365, 1000, 1000, 3)
32 
33     Returns
34     -------
35 
36     Dask array of all images stacked along the first dimension.  All images
37     will be treated as individual chunks
38     """
39     filenames = sorted(glob(filename))
40     if not filenames:
41         raise ValueError("No files found under name %s" % filename)
42 
43     name = 'imread-%s' % tokenize(filenames, map(os.path.getmtime, filenames))
44 
45     sample = sk_imread(filenames[0])
46 
47     dsk = dict(((name, i) + (0,) * len(sample.shape),
48                 (add_leading_dimension, (sk_imread, filename)))
49                 for i, filename in enumerate(filenames))
50 
51     chunks = ((1,) * len(filenames),) + tuple((d,) for d in sample.shape)
52 
53     return Array(dsk, name, chunks, sample.dtype)
54
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/dask/array/image.py b/dask/array/image.py
--- a/dask/array/image.py
+++ b/dask/array/image.py
@@ -13,7 +13,7 @@
     return x[None, ...]
 
 
-def imread(filename):
+def imread(filename, imread=None, preprocess=None):
     """ Read a stack of images into a dask array
 
     Parameters
@@ -21,6 +21,13 @@
 
     filename: string
         A globstring like 'myfile.*.png'
+    imread: function (optional)
+        Optionally provide custom imread function.
+        Function should expect a filename and produce a numpy array.
+        Defaults to ``skimage.io.imread``.
+    preprocess: function (optional)
+        Optionally provide custom function to preprocess the image.
+        Function should expect a numpy array for a single image.
 
     Example
     -------
@@ -36,17 +43,25 @@
     Dask array of all images stacked along the first dimension.  All images
     will be treated as individual chunks
     """
+    imread = imread or sk_imread
     filenames = sorted(glob(filename))
     if not filenames:
         raise ValueError("No files found under name %s" % filename)
 
     name = 'imread-%s' % tokenize(filenames, map(os.path.getmtime, filenames))
 
-    sample = sk_imread(filenames[0])
-
-    dsk = dict(((name, i) + (0,) * len(sample.shape),
-                (add_leading_dimension, (sk_imread, filename)))
-                for i, filename in enumerate(filenames))
+    sample = imread(filenames[0])
+    if preprocess:
+        sample = preprocess(sample)
+
+    keys = [(name, i) + (0,) * len(sample.shape) for i in range(len(filenames))]
+    if preprocess:
+        values = [(add_leading_dimension, (preprocess, (imread, filename)))
+                  for filename in filenames]
+    else:
+        values = [(add_leading_dimension, (imread, filename))
+                  for filename in filenames]
+    dsk = dict(zip(keys, values))
 
     chunks = ((1,) * len(filenames),) + tuple((d,) for d in sample.shape)

{"golden_diff": "diff --git a/dask/array/image.py b/dask/array/image.py\n--- a/dask/array/image.py\n+++ b/dask/array/image.py\n@@ -13,7 +13,7 @@\n     return x[None, ...]\n \n \n-def imread(filename):\n+def imread(filename, imread=None, preprocess=None):\n     \"\"\" Read a stack of images into a dask array\n \n     Parameters\n@@ -21,6 +21,13 @@\n \n     filename: string\n         A globstring like 'myfile.*.png'\n+    imread: function (optional)\n+        Optionally provide custom imread function.\n+        Function should expect a filename and produce a numpy array.\n+        Defaults to ``skimage.io.imread``.\n+    preprocess: function (optional)\n+        Optionally provide custom function to preprocess the image.\n+        Function should expect a numpy array for a single image.\n \n     Example\n     -------\n@@ -36,17 +43,25 @@\n     Dask array of all images stacked along the first dimension.  All images\n     will be treated as individual chunks\n     \"\"\"\n+    imread = imread or sk_imread\n     filenames = sorted(glob(filename))\n     if not filenames:\n         raise ValueError(\"No files found under name %s\" % filename)\n \n     name = 'imread-%s' % tokenize(filenames, map(os.path.getmtime, filenames))\n \n-    sample = sk_imread(filenames[0])\n-\n-    dsk = dict(((name, i) + (0,) * len(sample.shape),\n-                (add_leading_dimension, (sk_imread, filename)))\n-                for i, filename in enumerate(filenames))\n+    sample = imread(filenames[0])\n+    if preprocess:\n+        sample = preprocess(sample)\n+\n+    keys = [(name, i) + (0,) * len(sample.shape) for i in range(len(filenames))]\n+    if preprocess:\n+        values = [(add_leading_dimension, (preprocess, (imread, filename)))\n+                  for filename in filenames]\n+    else:\n+        values = [(add_leading_dimension, (imread, filename))\n+                  for filename in filenames]\n+    dsk = dict(zip(keys, values))\n \n     chunks = ((1,) * len(filenames),) + tuple((d,) for d in sample.shape)\n", "issue": "Additional improvement for da.image.imread\nI think following 2 improvements make the function better.\n#### 1. Allow custom `imread` function.\n\nSome prefer `opencv` which reads color in BGR order, otherwise `skimage` reads in RGB order. Adding `dialect` option (like `dialect='skimage'` or `dialect='cv'`) or accept different file read function may better.\n#### 2. Allow custom preprocessing function.\n\nIn image processing, input images may have different sizes. In these case, preprocessing is needed between image read and array creation. This preprocessing function must return the same size of array on user's responsibility.\n\n", "before_files": [{"content": "from glob import glob\nimport os\n\ntry:\n    from skimage.io import imread as sk_imread\nexcept ImportError:\n    pass\n\nfrom .core import Array\nfrom ..base import tokenize\n\ndef add_leading_dimension(x):\n    return x[None, ...]\n\n\ndef imread(filename):\n    \"\"\" Read a stack of images into a dask array\n\n    Parameters\n    ----------\n\n    filename: string\n        A globstring like 'myfile.*.png'\n\n    Example\n    -------\n\n    >>> from dask.array.image import imread\n    >>> im = imread('2015-*-*.png')  # doctest: +SKIP\n    >>> im.shape  # doctest: +SKIP\n    (365, 1000, 1000, 3)\n\n    Returns\n    -------\n\n    Dask array of all images stacked along the first dimension.  All images\n    will be treated as individual chunks\n    \"\"\"\n    filenames = sorted(glob(filename))\n    if not filenames:\n        raise ValueError(\"No files found under name %s\" % filename)\n\n    name = 'imread-%s' % tokenize(filenames, map(os.path.getmtime, filenames))\n\n    sample = sk_imread(filenames[0])\n\n    dsk = dict(((name, i) + (0,) * len(sample.shape),\n                (add_leading_dimension, (sk_imread, filename)))\n                for i, filename in enumerate(filenames))\n\n    chunks = ((1,) * len(filenames),) + tuple((d,) for d in sample.shape)\n\n    return Array(dsk, name, chunks, sample.dtype)\n", "path": "dask/array/image.py"}], "after_files": [{"content": "from glob import glob\nimport os\n\ntry:\n    from skimage.io import imread as sk_imread\nexcept ImportError:\n    pass\n\nfrom .core import Array\nfrom ..base import tokenize\n\ndef add_leading_dimension(x):\n    return x[None, ...]\n\n\ndef imread(filename, imread=None, preprocess=None):\n    \"\"\" Read a stack of images into a dask array\n\n    Parameters\n    ----------\n\n    filename: string\n        A globstring like 'myfile.*.png'\n    imread: function (optional)\n        Optionally provide custom imread function.\n        Function should expect a filename and produce a numpy array.\n        Defaults to ``skimage.io.imread``.\n    preprocess: function (optional)\n        Optionally provide custom function to preprocess the image.\n        Function should expect a numpy array for a single image.\n\n    Example\n    -------\n\n    >>> from dask.array.image import imread\n    >>> im = imread('2015-*-*.png')  # doctest: +SKIP\n    >>> im.shape  # doctest: +SKIP\n    (365, 1000, 1000, 3)\n\n    Returns\n    -------\n\n    Dask array of all images stacked along the first dimension.  All images\n    will be treated as individual chunks\n    \"\"\"\n    imread = imread or sk_imread\n    filenames = sorted(glob(filename))\n    if not filenames:\n        raise ValueError(\"No files found under name %s\" % filename)\n\n    name = 'imread-%s' % tokenize(filenames, map(os.path.getmtime, filenames))\n\n    sample = imread(filenames[0])\n    if preprocess:\n        sample = preprocess(sample)\n\n    keys = [(name, i) + (0,) * len(sample.shape) for i in range(len(filenames))]\n    if preprocess:\n        values = [(add_leading_dimension, (preprocess, (imread, filename)))\n                  for filename in filenames]\n    else:\n        values = [(add_leading_dimension, (imread, filename))\n                  for filename in filenames]\n    dsk = dict(zip(keys, values))\n\n    chunks = ((1,) * len(filenames),) + tuple((d,) for d in sample.shape)\n\n    return Array(dsk, name, chunks, sample.dtype)\n", "path": "dask/array/image.py"}]}