We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
bug: imsave cannot detect right extension of pathlib 
imsave cannot detect right extension of pathlib 

```python
from pathlib import Path
from  skimage import io

filename = Path("out.jpg")
io.imsave(filename, im) # this saves im as a png file though the extension is jpg

io.imsave("out.jpg", im) #this is working correctly
io.imsave(str(filename), im) #this is working correctly
```

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `skimage/io/_io.py`
Content:
```
1 import pathlib
2 
3 import numpy as np
4 
5 from .._shared.utils import warn
6 from ..exposure import is_low_contrast
7 from ..color.colorconv import rgb2gray, rgba2rgb
8 from ..io.manage_plugins import call_plugin
9 from .util import file_or_url_context
10 
11 
12 __all__ = ['imread', 'imsave', 'imshow', 'show',
13            'imread_collection', 'imshow_collection']
14 
15 
16 def imread(fname, as_gray=False, plugin=None, **plugin_args):
17     """Load an image from file.
18 
19     Parameters
20     ----------
21     fname : string
22         Image file name, e.g. ``test.jpg`` or URL.
23     as_gray : bool, optional
24         If True, convert color images to gray-scale (64-bit floats).
25         Images that are already in gray-scale format are not converted.
26     plugin : str, optional
27         Name of plugin to use.  By default, the different plugins are
28         tried (starting with imageio) until a suitable
29         candidate is found.  If not given and fname is a tiff file, the
30         tifffile plugin will be used.
31 
32     Other Parameters
33     ----------------
34     plugin_args : keywords
35         Passed to the given plugin.
36 
37     Returns
38     -------
39     img_array : ndarray
40         The different color bands/channels are stored in the
41         third dimension, such that a gray-image is MxN, an
42         RGB-image MxNx3 and an RGBA-image MxNx4.
43 
44     """
45     if isinstance(fname, pathlib.Path):
46         fname = str(fname.resolve())
47 
48     if plugin is None and hasattr(fname, 'lower'):
49         if fname.lower().endswith(('.tiff', '.tif')):
50             plugin = 'tifffile'
51 
52     with file_or_url_context(fname) as fname:
53         img = call_plugin('imread', fname, plugin=plugin, **plugin_args)
54 
55     if not hasattr(img, 'ndim'):
56         return img
57 
58     if img.ndim > 2:
59         if img.shape[-1] not in (3, 4) and img.shape[-3] in (3, 4):
60             img = np.swapaxes(img, -1, -3)
61             img = np.swapaxes(img, -2, -3)
62 
63         if as_gray:
64             if img.shape[2] == 4:
65                 img = rgba2rgb(img)
66             img = rgb2gray(img)
67 
68     return img
69 
70 
71 def imread_collection(load_pattern, conserve_memory=True,
72                       plugin=None, **plugin_args):
73     """
74     Load a collection of images.
75 
76     Parameters
77     ----------
78     load_pattern : str or list
79         List of objects to load. These are usually filenames, but may
80         vary depending on the currently active plugin.  See the docstring
81         for ``ImageCollection`` for the default behaviour of this parameter.
82     conserve_memory : bool, optional
83         If True, never keep more than one in memory at a specific
84         time.  Otherwise, images will be cached once they are loaded.
85 
86     Returns
87     -------
88     ic : ImageCollection
89         Collection of images.
90 
91     Other Parameters
92     ----------------
93     plugin_args : keywords
94         Passed to the given plugin.
95 
96     """
97     return call_plugin('imread_collection', load_pattern, conserve_memory,
98                        plugin=plugin, **plugin_args)
99 
100 
101 def imsave(fname, arr, plugin=None, check_contrast=True, **plugin_args):
102     """Save an image to file.
103 
104     Parameters
105     ----------
106     fname : str
107         Target filename.
108     arr : ndarray of shape (M,N) or (M,N,3) or (M,N,4)
109         Image data.
110     plugin : str, optional
111         Name of plugin to use.  By default, the different plugins are
112         tried (starting with imageio) until a suitable
113         candidate is found.  If not given and fname is a tiff file, the
114         tifffile plugin will be used.
115     check_contrast : bool, optional
116         Check for low contrast and print warning (default: True).
117 
118     Other Parameters
119     ----------------
120     plugin_args : keywords
121         Passed to the given plugin.
122 
123     Notes
124     -----
125     When saving a JPEG, the compression ratio may be controlled using the
126     ``quality`` keyword argument which is an integer with values in [1, 100]
127     where 1 is worst quality and smallest file size, and 100 is best quality
128     and largest file size (default 75).  This is only available when using
129     the PIL and imageio plugins.
130     """
131     if plugin is None and hasattr(fname, 'lower'):
132         if fname.lower().endswith(('.tiff', '.tif')):
133             plugin = 'tifffile'
134     if arr.dtype == bool:
135         warn('%s is a boolean image: setting True to 255 and False to 0. '
136              'To silence this warning, please convert the image using '
137              'img_as_ubyte.' % fname, stacklevel=2)
138         arr = arr.astype('uint8') * 255
139     if check_contrast and is_low_contrast(arr):
140         warn('%s is a low contrast image' % fname)
141     return call_plugin('imsave', fname, arr, plugin=plugin, **plugin_args)
142 
143 
144 def imshow(arr, plugin=None, **plugin_args):
145     """Display an image.
146 
147     Parameters
148     ----------
149     arr : ndarray or str
150         Image data or name of image file.
151     plugin : str
152         Name of plugin to use.  By default, the different plugins are
153         tried (starting with imageio) until a suitable
154         candidate is found.
155 
156     Other Parameters
157     ----------------
158     plugin_args : keywords
159         Passed to the given plugin.
160 
161     """
162     if isinstance(arr, str):
163         arr = call_plugin('imread', arr, plugin=plugin)
164     return call_plugin('imshow', arr, plugin=plugin, **plugin_args)
165 
166 
167 def imshow_collection(ic, plugin=None, **plugin_args):
168     """Display a collection of images.
169 
170     Parameters
171     ----------
172     ic : ImageCollection
173         Collection to display.
174     plugin : str
175         Name of plugin to use.  By default, the different plugins are
176         tried until a suitable candidate is found.
177 
178     Other Parameters
179     ----------------
180     plugin_args : keywords
181         Passed to the given plugin.
182 
183     """
184     return call_plugin('imshow_collection', ic, plugin=plugin, **plugin_args)
185 
186 
187 def show():
188     '''Display pending images.
189 
190     Launch the event loop of the current gui plugin, and display all
191     pending images, queued via `imshow`. This is required when using
192     `imshow` from non-interactive scripts.
193 
194     A call to `show` will block execution of code until all windows
195     have been closed.
196 
197     Examples
198     --------
199     >>> import skimage.io as io
200 
201     >>> rng = np.random.default_rng()
202     >>> for i in range(4):
203     ...     ax_im = io.imshow(rng.random((50, 50)))
204     >>> io.show() # doctest: +SKIP
205 
206     '''
207     return call_plugin('_app_show')
208
```
--- 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/skimage/io/_io.py b/skimage/io/_io.py
--- a/skimage/io/_io.py
+++ b/skimage/io/_io.py
@@ -128,6 +128,8 @@
     and largest file size (default 75).  This is only available when using
     the PIL and imageio plugins.
     """
+    if isinstance(fname, pathlib.Path):
+        fname = str(fname.resolve())
     if plugin is None and hasattr(fname, 'lower'):
         if fname.lower().endswith(('.tiff', '.tif')):
             plugin = 'tifffile'

{"golden_diff": "diff --git a/skimage/io/_io.py b/skimage/io/_io.py\n--- a/skimage/io/_io.py\n+++ b/skimage/io/_io.py\n@@ -128,6 +128,8 @@\n     and largest file size (default 75).  This is only available when using\n     the PIL and imageio plugins.\n     \"\"\"\n+    if isinstance(fname, pathlib.Path):\n+        fname = str(fname.resolve())\n     if plugin is None and hasattr(fname, 'lower'):\n         if fname.lower().endswith(('.tiff', '.tif')):\n             plugin = 'tifffile'\n", "issue": "bug: imsave cannot detect right extension of pathlib \nimsave cannot detect right extension of pathlib \r\n\r\n```python\r\nfrom pathlib import Path\r\nfrom  skimage import io\r\n\r\nfilename = Path(\"out.jpg\")\r\nio.imsave(filename, im) # this saves im as a png file though the extension is jpg\r\n\r\nio.imsave(\"out.jpg\", im) #this is working correctly\r\nio.imsave(str(filename), im) #this is working correctly\r\n```\n", "before_files": [{"content": "import pathlib\n\nimport numpy as np\n\nfrom .._shared.utils import warn\nfrom ..exposure import is_low_contrast\nfrom ..color.colorconv import rgb2gray, rgba2rgb\nfrom ..io.manage_plugins import call_plugin\nfrom .util import file_or_url_context\n\n\n__all__ = ['imread', 'imsave', 'imshow', 'show',\n           'imread_collection', 'imshow_collection']\n\n\ndef imread(fname, as_gray=False, plugin=None, **plugin_args):\n    \"\"\"Load an image from file.\n\n    Parameters\n    ----------\n    fname : string\n        Image file name, e.g. ``test.jpg`` or URL.\n    as_gray : bool, optional\n        If True, convert color images to gray-scale (64-bit floats).\n        Images that are already in gray-scale format are not converted.\n    plugin : str, optional\n        Name of plugin to use.  By default, the different plugins are\n        tried (starting with imageio) until a suitable\n        candidate is found.  If not given and fname is a tiff file, the\n        tifffile plugin will be used.\n\n    Other Parameters\n    ----------------\n    plugin_args : keywords\n        Passed to the given plugin.\n\n    Returns\n    -------\n    img_array : ndarray\n        The different color bands/channels are stored in the\n        third dimension, such that a gray-image is MxN, an\n        RGB-image MxNx3 and an RGBA-image MxNx4.\n\n    \"\"\"\n    if isinstance(fname, pathlib.Path):\n        fname = str(fname.resolve())\n\n    if plugin is None and hasattr(fname, 'lower'):\n        if fname.lower().endswith(('.tiff', '.tif')):\n            plugin = 'tifffile'\n\n    with file_or_url_context(fname) as fname:\n        img = call_plugin('imread', fname, plugin=plugin, **plugin_args)\n\n    if not hasattr(img, 'ndim'):\n        return img\n\n    if img.ndim > 2:\n        if img.shape[-1] not in (3, 4) and img.shape[-3] in (3, 4):\n            img = np.swapaxes(img, -1, -3)\n            img = np.swapaxes(img, -2, -3)\n\n        if as_gray:\n            if img.shape[2] == 4:\n                img = rgba2rgb(img)\n            img = rgb2gray(img)\n\n    return img\n\n\ndef imread_collection(load_pattern, conserve_memory=True,\n                      plugin=None, **plugin_args):\n    \"\"\"\n    Load a collection of images.\n\n    Parameters\n    ----------\n    load_pattern : str or list\n        List of objects to load. These are usually filenames, but may\n        vary depending on the currently active plugin.  See the docstring\n        for ``ImageCollection`` for the default behaviour of this parameter.\n    conserve_memory : bool, optional\n        If True, never keep more than one in memory at a specific\n        time.  Otherwise, images will be cached once they are loaded.\n\n    Returns\n    -------\n    ic : ImageCollection\n        Collection of images.\n\n    Other Parameters\n    ----------------\n    plugin_args : keywords\n        Passed to the given plugin.\n\n    \"\"\"\n    return call_plugin('imread_collection', load_pattern, conserve_memory,\n                       plugin=plugin, **plugin_args)\n\n\ndef imsave(fname, arr, plugin=None, check_contrast=True, **plugin_args):\n    \"\"\"Save an image to file.\n\n    Parameters\n    ----------\n    fname : str\n        Target filename.\n    arr : ndarray of shape (M,N) or (M,N,3) or (M,N,4)\n        Image data.\n    plugin : str, optional\n        Name of plugin to use.  By default, the different plugins are\n        tried (starting with imageio) until a suitable\n        candidate is found.  If not given and fname is a tiff file, the\n        tifffile plugin will be used.\n    check_contrast : bool, optional\n        Check for low contrast and print warning (default: True).\n\n    Other Parameters\n    ----------------\n    plugin_args : keywords\n        Passed to the given plugin.\n\n    Notes\n    -----\n    When saving a JPEG, the compression ratio may be controlled using the\n    ``quality`` keyword argument which is an integer with values in [1, 100]\n    where 1 is worst quality and smallest file size, and 100 is best quality\n    and largest file size (default 75).  This is only available when using\n    the PIL and imageio plugins.\n    \"\"\"\n    if plugin is None and hasattr(fname, 'lower'):\n        if fname.lower().endswith(('.tiff', '.tif')):\n            plugin = 'tifffile'\n    if arr.dtype == bool:\n        warn('%s is a boolean image: setting True to 255 and False to 0. '\n             'To silence this warning, please convert the image using '\n             'img_as_ubyte.' % fname, stacklevel=2)\n        arr = arr.astype('uint8') * 255\n    if check_contrast and is_low_contrast(arr):\n        warn('%s is a low contrast image' % fname)\n    return call_plugin('imsave', fname, arr, plugin=plugin, **plugin_args)\n\n\ndef imshow(arr, plugin=None, **plugin_args):\n    \"\"\"Display an image.\n\n    Parameters\n    ----------\n    arr : ndarray or str\n        Image data or name of image file.\n    plugin : str\n        Name of plugin to use.  By default, the different plugins are\n        tried (starting with imageio) until a suitable\n        candidate is found.\n\n    Other Parameters\n    ----------------\n    plugin_args : keywords\n        Passed to the given plugin.\n\n    \"\"\"\n    if isinstance(arr, str):\n        arr = call_plugin('imread', arr, plugin=plugin)\n    return call_plugin('imshow', arr, plugin=plugin, **plugin_args)\n\n\ndef imshow_collection(ic, plugin=None, **plugin_args):\n    \"\"\"Display a collection of images.\n\n    Parameters\n    ----------\n    ic : ImageCollection\n        Collection to display.\n    plugin : str\n        Name of plugin to use.  By default, the different plugins are\n        tried until a suitable candidate is found.\n\n    Other Parameters\n    ----------------\n    plugin_args : keywords\n        Passed to the given plugin.\n\n    \"\"\"\n    return call_plugin('imshow_collection', ic, plugin=plugin, **plugin_args)\n\n\ndef show():\n    '''Display pending images.\n\n    Launch the event loop of the current gui plugin, and display all\n    pending images, queued via `imshow`. This is required when using\n    `imshow` from non-interactive scripts.\n\n    A call to `show` will block execution of code until all windows\n    have been closed.\n\n    Examples\n    --------\n    >>> import skimage.io as io\n\n    >>> rng = np.random.default_rng()\n    >>> for i in range(4):\n    ...     ax_im = io.imshow(rng.random((50, 50)))\n    >>> io.show() # doctest: +SKIP\n\n    '''\n    return call_plugin('_app_show')\n", "path": "skimage/io/_io.py"}], "after_files": [{"content": "import pathlib\n\nimport numpy as np\n\nfrom .._shared.utils import warn\nfrom ..exposure import is_low_contrast\nfrom ..color.colorconv import rgb2gray, rgba2rgb\nfrom ..io.manage_plugins import call_plugin\nfrom .util import file_or_url_context\n\n\n__all__ = ['imread', 'imsave', 'imshow', 'show',\n           'imread_collection', 'imshow_collection']\n\n\ndef imread(fname, as_gray=False, plugin=None, **plugin_args):\n    \"\"\"Load an image from file.\n\n    Parameters\n    ----------\n    fname : string\n        Image file name, e.g. ``test.jpg`` or URL.\n    as_gray : bool, optional\n        If True, convert color images to gray-scale (64-bit floats).\n        Images that are already in gray-scale format are not converted.\n    plugin : str, optional\n        Name of plugin to use.  By default, the different plugins are\n        tried (starting with imageio) until a suitable\n        candidate is found.  If not given and fname is a tiff file, the\n        tifffile plugin will be used.\n\n    Other Parameters\n    ----------------\n    plugin_args : keywords\n        Passed to the given plugin.\n\n    Returns\n    -------\n    img_array : ndarray\n        The different color bands/channels are stored in the\n        third dimension, such that a gray-image is MxN, an\n        RGB-image MxNx3 and an RGBA-image MxNx4.\n\n    \"\"\"\n    if isinstance(fname, pathlib.Path):\n        fname = str(fname.resolve())\n\n    if plugin is None and hasattr(fname, 'lower'):\n        if fname.lower().endswith(('.tiff', '.tif')):\n            plugin = 'tifffile'\n\n    with file_or_url_context(fname) as fname:\n        img = call_plugin('imread', fname, plugin=plugin, **plugin_args)\n\n    if not hasattr(img, 'ndim'):\n        return img\n\n    if img.ndim > 2:\n        if img.shape[-1] not in (3, 4) and img.shape[-3] in (3, 4):\n            img = np.swapaxes(img, -1, -3)\n            img = np.swapaxes(img, -2, -3)\n\n        if as_gray:\n            if img.shape[2] == 4:\n                img = rgba2rgb(img)\n            img = rgb2gray(img)\n\n    return img\n\n\ndef imread_collection(load_pattern, conserve_memory=True,\n                      plugin=None, **plugin_args):\n    \"\"\"\n    Load a collection of images.\n\n    Parameters\n    ----------\n    load_pattern : str or list\n        List of objects to load. These are usually filenames, but may\n        vary depending on the currently active plugin.  See the docstring\n        for ``ImageCollection`` for the default behaviour of this parameter.\n    conserve_memory : bool, optional\n        If True, never keep more than one in memory at a specific\n        time.  Otherwise, images will be cached once they are loaded.\n\n    Returns\n    -------\n    ic : ImageCollection\n        Collection of images.\n\n    Other Parameters\n    ----------------\n    plugin_args : keywords\n        Passed to the given plugin.\n\n    \"\"\"\n    return call_plugin('imread_collection', load_pattern, conserve_memory,\n                       plugin=plugin, **plugin_args)\n\n\ndef imsave(fname, arr, plugin=None, check_contrast=True, **plugin_args):\n    \"\"\"Save an image to file.\n\n    Parameters\n    ----------\n    fname : str\n        Target filename.\n    arr : ndarray of shape (M,N) or (M,N,3) or (M,N,4)\n        Image data.\n    plugin : str, optional\n        Name of plugin to use.  By default, the different plugins are\n        tried (starting with imageio) until a suitable\n        candidate is found.  If not given and fname is a tiff file, the\n        tifffile plugin will be used.\n    check_contrast : bool, optional\n        Check for low contrast and print warning (default: True).\n\n    Other Parameters\n    ----------------\n    plugin_args : keywords\n        Passed to the given plugin.\n\n    Notes\n    -----\n    When saving a JPEG, the compression ratio may be controlled using the\n    ``quality`` keyword argument which is an integer with values in [1, 100]\n    where 1 is worst quality and smallest file size, and 100 is best quality\n    and largest file size (default 75).  This is only available when using\n    the PIL and imageio plugins.\n    \"\"\"\n    if isinstance(fname, pathlib.Path):\n        fname = str(fname.resolve())\n    if plugin is None and hasattr(fname, 'lower'):\n        if fname.lower().endswith(('.tiff', '.tif')):\n            plugin = 'tifffile'\n    if arr.dtype == bool:\n        warn('%s is a boolean image: setting True to 255 and False to 0. '\n             'To silence this warning, please convert the image using '\n             'img_as_ubyte.' % fname, stacklevel=2)\n        arr = arr.astype('uint8') * 255\n    if check_contrast and is_low_contrast(arr):\n        warn('%s is a low contrast image' % fname)\n    return call_plugin('imsave', fname, arr, plugin=plugin, **plugin_args)\n\n\ndef imshow(arr, plugin=None, **plugin_args):\n    \"\"\"Display an image.\n\n    Parameters\n    ----------\n    arr : ndarray or str\n        Image data or name of image file.\n    plugin : str\n        Name of plugin to use.  By default, the different plugins are\n        tried (starting with imageio) until a suitable\n        candidate is found.\n\n    Other Parameters\n    ----------------\n    plugin_args : keywords\n        Passed to the given plugin.\n\n    \"\"\"\n    if isinstance(arr, str):\n        arr = call_plugin('imread', arr, plugin=plugin)\n    return call_plugin('imshow', arr, plugin=plugin, **plugin_args)\n\n\ndef imshow_collection(ic, plugin=None, **plugin_args):\n    \"\"\"Display a collection of images.\n\n    Parameters\n    ----------\n    ic : ImageCollection\n        Collection to display.\n    plugin : str\n        Name of plugin to use.  By default, the different plugins are\n        tried until a suitable candidate is found.\n\n    Other Parameters\n    ----------------\n    plugin_args : keywords\n        Passed to the given plugin.\n\n    \"\"\"\n    return call_plugin('imshow_collection', ic, plugin=plugin, **plugin_args)\n\n\ndef show():\n    '''Display pending images.\n\n    Launch the event loop of the current gui plugin, and display all\n    pending images, queued via `imshow`. This is required when using\n    `imshow` from non-interactive scripts.\n\n    A call to `show` will block execution of code until all windows\n    have been closed.\n\n    Examples\n    --------\n    >>> import skimage.io as io\n\n    >>> rng = np.random.default_rng()\n    >>> for i in range(4):\n    ...     ax_im = io.imshow(rng.random((50, 50)))\n    >>> io.show() # doctest: +SKIP\n\n    '''\n    return call_plugin('_app_show')\n", "path": "skimage/io/_io.py"}]}