We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
BytesIO/StringIO break pn.pane.image if called second time
#### ALL software version info
Panel: 0.10.0.post7+gb5cf6928

#### Description of expected behavior and the observed behavior
When having a BytesIO/StringIO object as input to pn.pane.image it will crash the second time a widget is called.
I don´t know if it a feature or a bug... I have made a simple implementation of a fix, if it is a bug [here](https://github.com/Hoxbro/panel/commit/af03e001a23d1e1cea065f85abfb4e0176d0d688).


#### Complete, minimal, self-contained example code that reproduces the issue

```python
import os

import param
import panel as pn


class ImageExample(param.Parameterized):
    def __init__(self, **params):
        self.button = pn.widgets.Button(name="Create Animation", button_type="primary")
        self.break_ = pn.widgets.Button(name="Break Animation", button_type="primary")
        super().__init__(**params)
        self.gif = None

    @param.depends(pn.state.param.busy)
    def animation(self, busy):
        return None if busy else self.gif

    @param.depends("button.clicks")
    def _create_animation(self):
        # it could be any gif... :)
        self.gif = pn.pane.GIF(open(os.path.join(os.path.dirname(__file__),'index.gif'), 'rb'))

    @param.depends("break_.clicks")
    def _break_animation(self):
        pass


ie = ImageExample()
pn.Column(
    ie.button,
    ie.break_,
    ie.animation,
    ie._create_animation,
).servable()


```


#### Screenshots or screencasts of the bug in action
![bug](https://user-images.githubusercontent.com/19758978/97351723-6e509a00-1892-11eb-802f-af19e6ed1e98.gif)

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `panel/pane/image.py`
Content:
```
1 """
2 Contains Image panes including renderers for PNG, SVG, GIF and JPG
3 file types.
4 """
5 from __future__ import absolute_import, division, unicode_literals
6 
7 import base64
8 
9 from io import BytesIO
10 from six import string_types
11 
12 import param
13 
14 from .markup import escape, DivPaneBase
15 from ..util import isfile, isurl
16 
17 
18 class ImageBase(DivPaneBase):
19     """
20     Encodes an image as base64 and wraps it in a Bokeh Div model.
21     This is an abstract base class that needs the image type
22     to be specified and specific code for determining the image shape.
23 
24     The imgtype determines the filetype, extension, and MIME type for
25     this image. Each image type (png,jpg,gif) has a base class that
26     supports anything with a `_repr_X_` method (where X is `png`,
27     `gif`, etc.), a local file with the given file extension, or a
28     HTTP(S) url with the given extension.  Subclasses of each type can
29     provide their own way of obtaining or generating a PNG.
30     """
31 
32     alt_text = param.String(default=None, doc="""
33         alt text to add to the image tag. The alt text is shown when a
34         user cannot load or display the image.""")
35 
36     link_url = param.String(default=None, doc="""
37         A link URL to make the image clickable and link to some other
38         website.""")
39 
40     embed = param.Boolean(default=True, doc="""
41         Whether to embed the image as base64.""")
42 
43     imgtype = 'None'
44 
45     _rerender_params = ['alt_text', 'link_url', 'embed', 'object', 'style']
46 
47     _target_transforms = {'object': """'<img src="' + value + '"></img>'"""}
48 
49     __abstract = True
50 
51     @classmethod
52     def applies(cls, obj):
53         imgtype = cls.imgtype
54         if hasattr(obj, '_repr_{}_'.format(imgtype)):
55             return True
56         if isinstance(obj, string_types):
57             if isfile(obj) and obj.endswith('.'+imgtype):
58                 return True
59             if isurl(obj, [cls.imgtype]):
60                 return True
61             elif isurl(obj, None):
62                 return 0
63         if hasattr(obj, 'read'):  # Check for file like object
64             return True
65         return False
66 
67     def _type_error(self, object):
68         if isinstance(object, string_types):
69             raise ValueError("%s pane cannot parse string that is not a filename "
70                              "or URL." % type(self).__name__)
71         super(ImageBase, self)._type_error(object)
72 
73     def _img(self):
74         if hasattr(self.object, '_repr_{}_'.format(self.imgtype)):
75             return getattr(self.object, '_repr_' + self.imgtype + '_')()
76         if isinstance(self.object, string_types):
77             if isfile(self.object):
78                 with open(self.object, 'rb') as f:
79                     return f.read()
80         if hasattr(self.object, 'read'):
81             return self.object.read()
82         if isurl(self.object, None):
83             import requests
84             r = requests.request(url=self.object, method='GET')
85             return r.content
86 
87     def _b64(self):
88         data = self._img()
89         if not isinstance(data, bytes):
90             data = data.encode('utf-8')
91         b64 = base64.b64encode(data).decode("utf-8")
92         return "data:image/"+self.imgtype+f";base64,{b64}"
93 
94     def _imgshape(self, data):
95         """Calculate and return image width,height"""
96         raise NotImplementedError
97 
98     def _get_properties(self):
99         p = super(ImageBase, self)._get_properties()
100         if self.object is None:
101             return dict(p, text='<img></img>')
102         data = self._img()
103         if not isinstance(data, bytes):
104             data = base64.b64decode(data)
105         width, height = self._imgshape(data)
106         if self.width is not None:
107             if self.height is None:
108                 height = int((self.width/width)*height)
109             else:
110                 height = self.height
111             width = self.width
112         elif self.height is not None:
113             width = int((self.height/height)*width)
114             height = self.height
115         if not self.embed:
116             src = self.object
117         else:
118             b64 = base64.b64encode(data).decode("utf-8")
119             src = "data:image/"+self.imgtype+";base64,{b64}".format(b64=b64)
120 
121         smode = self.sizing_mode
122         if smode in ['fixed', None]:
123             w, h = '%spx' % width, '%spx' % height
124         elif smode == 'stretch_both':
125             w, h = '100%', '100%'
126         elif smode == 'stretch_width':
127             w, h = '%spx' % width, '100%'
128         elif smode == 'stretch_height':
129             w, h = '100%', '%spx' % height
130         elif smode == 'scale_height':
131             w, h = 'auto', '100%'
132         else:
133             w, h = '100%', 'auto'
134 
135         html = '<img src="{src}" width="{width}" height="{height}" alt="{alt}"></img>'.format(
136             src=src, width=w, height=h, alt=self.alt_text or '')
137 
138         if self.link_url:
139             html = '<a href="{url}" target="_blank">{html}</a>'.format(
140                 url=self.link_url, html=html)
141 
142         return dict(p, width=width, height=height, text=escape(html))
143 
144 
145 class PNG(ImageBase):
146 
147     imgtype = 'png'
148 
149     @classmethod
150     def _imgshape(cls, data):
151         import struct
152         w, h = struct.unpack('>LL', data[16:24])
153         return int(w), int(h)
154 
155 
156 class GIF(ImageBase):
157 
158     imgtype = 'gif'
159 
160     @classmethod
161     def _imgshape(cls, data):
162         import struct
163         w, h = struct.unpack("<HH", data[6:10])
164         return int(w), int(h)
165 
166 
167 class JPG(ImageBase):
168 
169     imgtype = 'jpg'
170 
171     @classmethod
172     def _imgshape(cls, data):
173         import struct
174         b = BytesIO(data)
175         b.read(2)
176         c = b.read(1)
177         while (c and ord(c) != 0xDA):
178             while (ord(c) != 0xFF): c = b.read(1)
179             while (ord(c) == 0xFF): c = b.read(1)
180             if (ord(c) >= 0xC0 and ord(c) <= 0xC3):
181                 b.read(3)
182                 h, w = struct.unpack(">HH", b.read(4))
183                 break
184             else:
185                 b.read(int(struct.unpack(">H", b.read(2))[0])-2)
186             c = b.read(1)
187         return int(w), int(h)
188 
189 
190 class SVG(ImageBase):
191 
192     encode = param.Boolean(default=False, doc="""
193         Whether to enable base64 encoding of the SVG, base64 encoded
194         SVGs do not support links.""")
195 
196     imgtype = 'svg'
197 
198     _rerender_params = ImageBase._rerender_params + ['encode']
199 
200     @classmethod
201     def applies(cls, obj):
202         return (super(SVG, cls).applies(obj) or
203                 (isinstance(obj, string_types) and obj.lstrip().startswith('<svg')))
204 
205     def _type_error(self, object):
206         if isinstance(object, string_types):
207             raise ValueError("%s pane cannot parse string that is not a filename, "
208                              "URL or a SVG XML contents." % type(self).__name__)
209         super(SVG, self)._type_error(object)
210 
211     def _img(self):
212         if (isinstance(self.object, string_types) and
213             self.object.lstrip().startswith('<svg')):
214             return self.object
215         return super(SVG, self)._img()
216 
217     def _b64(self):
218         data = self._img()
219         if not isinstance(data, bytes):
220             data = data.encode('utf-8')
221         b64 = base64.b64encode(data).decode("utf-8")
222         return f"data:image/svg+xml;base64,{b64}"
223 
224     def _imgshape(self, data):
225         return (self.width, self.height)
226 
227     def _get_properties(self):
228         p = super(ImageBase, self)._get_properties()
229         if self.object is None:
230             return dict(p, text='<img></img>')
231         data = self._img()
232         width, height = self._imgshape(data)
233         if not isinstance(data, bytes):
234             data = data.encode('utf-8')
235 
236         if self.encode:
237             b64 = base64.b64encode(data).decode("utf-8")
238             src = "data:image/svg+xml;base64,{b64}".format(b64=b64)
239             html = "<img src='{src}' width={width} height={height}></img>".format(
240                 src=src, width=width, height=height
241             )
242         else:
243             html = data.decode("utf-8")
244         return dict(p, width=width, height=height, text=escape(html))
245
```
--- 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/panel/pane/image.py b/panel/pane/image.py
--- a/panel/pane/image.py
+++ b/panel/pane/image.py
@@ -78,6 +78,8 @@
                 with open(self.object, 'rb') as f:
                     return f.read()
         if hasattr(self.object, 'read'):
+            if hasattr(self.object, 'seek'):
+                self.object.seek(0)
             return self.object.read()
         if isurl(self.object, None):
             import requests

{"golden_diff": "diff --git a/panel/pane/image.py b/panel/pane/image.py\n--- a/panel/pane/image.py\n+++ b/panel/pane/image.py\n@@ -78,6 +78,8 @@\n                 with open(self.object, 'rb') as f:\n                     return f.read()\n         if hasattr(self.object, 'read'):\n+            if hasattr(self.object, 'seek'):\n+                self.object.seek(0)\n             return self.object.read()\n         if isurl(self.object, None):\n             import requests\n", "issue": "BytesIO/StringIO break pn.pane.image if called second time\n#### ALL software version info\r\nPanel: 0.10.0.post7+gb5cf6928\r\n\r\n#### Description of expected behavior and the observed behavior\r\nWhen having a BytesIO/StringIO object as input to pn.pane.image it will crash the second time a widget is called.\r\nI don\u00b4t know if it a feature or a bug... I have made a simple implementation of a fix, if it is a bug [here](https://github.com/Hoxbro/panel/commit/af03e001a23d1e1cea065f85abfb4e0176d0d688).\r\n\r\n\r\n#### Complete, minimal, self-contained example code that reproduces the issue\r\n\r\n```python\r\nimport os\r\n\r\nimport param\r\nimport panel as pn\r\n\r\n\r\nclass ImageExample(param.Parameterized):\r\n    def __init__(self, **params):\r\n        self.button = pn.widgets.Button(name=\"Create Animation\", button_type=\"primary\")\r\n        self.break_ = pn.widgets.Button(name=\"Break Animation\", button_type=\"primary\")\r\n        super().__init__(**params)\r\n        self.gif = None\r\n\r\n    @param.depends(pn.state.param.busy)\r\n    def animation(self, busy):\r\n        return None if busy else self.gif\r\n\r\n    @param.depends(\"button.clicks\")\r\n    def _create_animation(self):\r\n        # it could be any gif... :)\r\n        self.gif = pn.pane.GIF(open(os.path.join(os.path.dirname(__file__),'index.gif'), 'rb'))\r\n\r\n    @param.depends(\"break_.clicks\")\r\n    def _break_animation(self):\r\n        pass\r\n\r\n\r\nie = ImageExample()\r\npn.Column(\r\n    ie.button,\r\n    ie.break_,\r\n    ie.animation,\r\n    ie._create_animation,\r\n).servable()\r\n\r\n\r\n```\r\n\r\n\r\n#### Screenshots or screencasts of the bug in action\r\n![bug](https://user-images.githubusercontent.com/19758978/97351723-6e509a00-1892-11eb-802f-af19e6ed1e98.gif)\n", "before_files": [{"content": "\"\"\"\nContains Image panes including renderers for PNG, SVG, GIF and JPG\nfile types.\n\"\"\"\nfrom __future__ import absolute_import, division, unicode_literals\n\nimport base64\n\nfrom io import BytesIO\nfrom six import string_types\n\nimport param\n\nfrom .markup import escape, DivPaneBase\nfrom ..util import isfile, isurl\n\n\nclass ImageBase(DivPaneBase):\n    \"\"\"\n    Encodes an image as base64 and wraps it in a Bokeh Div model.\n    This is an abstract base class that needs the image type\n    to be specified and specific code for determining the image shape.\n\n    The imgtype determines the filetype, extension, and MIME type for\n    this image. Each image type (png,jpg,gif) has a base class that\n    supports anything with a `_repr_X_` method (where X is `png`,\n    `gif`, etc.), a local file with the given file extension, or a\n    HTTP(S) url with the given extension.  Subclasses of each type can\n    provide their own way of obtaining or generating a PNG.\n    \"\"\"\n\n    alt_text = param.String(default=None, doc=\"\"\"\n        alt text to add to the image tag. The alt text is shown when a\n        user cannot load or display the image.\"\"\")\n\n    link_url = param.String(default=None, doc=\"\"\"\n        A link URL to make the image clickable and link to some other\n        website.\"\"\")\n\n    embed = param.Boolean(default=True, doc=\"\"\"\n        Whether to embed the image as base64.\"\"\")\n\n    imgtype = 'None'\n\n    _rerender_params = ['alt_text', 'link_url', 'embed', 'object', 'style']\n\n    _target_transforms = {'object': \"\"\"'<img src=\"' + value + '\"></img>'\"\"\"}\n\n    __abstract = True\n\n    @classmethod\n    def applies(cls, obj):\n        imgtype = cls.imgtype\n        if hasattr(obj, '_repr_{}_'.format(imgtype)):\n            return True\n        if isinstance(obj, string_types):\n            if isfile(obj) and obj.endswith('.'+imgtype):\n                return True\n            if isurl(obj, [cls.imgtype]):\n                return True\n            elif isurl(obj, None):\n                return 0\n        if hasattr(obj, 'read'):  # Check for file like object\n            return True\n        return False\n\n    def _type_error(self, object):\n        if isinstance(object, string_types):\n            raise ValueError(\"%s pane cannot parse string that is not a filename \"\n                             \"or URL.\" % type(self).__name__)\n        super(ImageBase, self)._type_error(object)\n\n    def _img(self):\n        if hasattr(self.object, '_repr_{}_'.format(self.imgtype)):\n            return getattr(self.object, '_repr_' + self.imgtype + '_')()\n        if isinstance(self.object, string_types):\n            if isfile(self.object):\n                with open(self.object, 'rb') as f:\n                    return f.read()\n        if hasattr(self.object, 'read'):\n            return self.object.read()\n        if isurl(self.object, None):\n            import requests\n            r = requests.request(url=self.object, method='GET')\n            return r.content\n\n    def _b64(self):\n        data = self._img()\n        if not isinstance(data, bytes):\n            data = data.encode('utf-8')\n        b64 = base64.b64encode(data).decode(\"utf-8\")\n        return \"data:image/\"+self.imgtype+f\";base64,{b64}\"\n\n    def _imgshape(self, data):\n        \"\"\"Calculate and return image width,height\"\"\"\n        raise NotImplementedError\n\n    def _get_properties(self):\n        p = super(ImageBase, self)._get_properties()\n        if self.object is None:\n            return dict(p, text='<img></img>')\n        data = self._img()\n        if not isinstance(data, bytes):\n            data = base64.b64decode(data)\n        width, height = self._imgshape(data)\n        if self.width is not None:\n            if self.height is None:\n                height = int((self.width/width)*height)\n            else:\n                height = self.height\n            width = self.width\n        elif self.height is not None:\n            width = int((self.height/height)*width)\n            height = self.height\n        if not self.embed:\n            src = self.object\n        else:\n            b64 = base64.b64encode(data).decode(\"utf-8\")\n            src = \"data:image/\"+self.imgtype+\";base64,{b64}\".format(b64=b64)\n\n        smode = self.sizing_mode\n        if smode in ['fixed', None]:\n            w, h = '%spx' % width, '%spx' % height\n        elif smode == 'stretch_both':\n            w, h = '100%', '100%'\n        elif smode == 'stretch_width':\n            w, h = '%spx' % width, '100%'\n        elif smode == 'stretch_height':\n            w, h = '100%', '%spx' % height\n        elif smode == 'scale_height':\n            w, h = 'auto', '100%'\n        else:\n            w, h = '100%', 'auto'\n\n        html = '<img src=\"{src}\" width=\"{width}\" height=\"{height}\" alt=\"{alt}\"></img>'.format(\n            src=src, width=w, height=h, alt=self.alt_text or '')\n\n        if self.link_url:\n            html = '<a href=\"{url}\" target=\"_blank\">{html}</a>'.format(\n                url=self.link_url, html=html)\n\n        return dict(p, width=width, height=height, text=escape(html))\n\n\nclass PNG(ImageBase):\n\n    imgtype = 'png'\n\n    @classmethod\n    def _imgshape(cls, data):\n        import struct\n        w, h = struct.unpack('>LL', data[16:24])\n        return int(w), int(h)\n\n\nclass GIF(ImageBase):\n\n    imgtype = 'gif'\n\n    @classmethod\n    def _imgshape(cls, data):\n        import struct\n        w, h = struct.unpack(\"<HH\", data[6:10])\n        return int(w), int(h)\n\n\nclass JPG(ImageBase):\n\n    imgtype = 'jpg'\n\n    @classmethod\n    def _imgshape(cls, data):\n        import struct\n        b = BytesIO(data)\n        b.read(2)\n        c = b.read(1)\n        while (c and ord(c) != 0xDA):\n            while (ord(c) != 0xFF): c = b.read(1)\n            while (ord(c) == 0xFF): c = b.read(1)\n            if (ord(c) >= 0xC0 and ord(c) <= 0xC3):\n                b.read(3)\n                h, w = struct.unpack(\">HH\", b.read(4))\n                break\n            else:\n                b.read(int(struct.unpack(\">H\", b.read(2))[0])-2)\n            c = b.read(1)\n        return int(w), int(h)\n\n\nclass SVG(ImageBase):\n\n    encode = param.Boolean(default=False, doc=\"\"\"\n        Whether to enable base64 encoding of the SVG, base64 encoded\n        SVGs do not support links.\"\"\")\n\n    imgtype = 'svg'\n\n    _rerender_params = ImageBase._rerender_params + ['encode']\n\n    @classmethod\n    def applies(cls, obj):\n        return (super(SVG, cls).applies(obj) or\n                (isinstance(obj, string_types) and obj.lstrip().startswith('<svg')))\n\n    def _type_error(self, object):\n        if isinstance(object, string_types):\n            raise ValueError(\"%s pane cannot parse string that is not a filename, \"\n                             \"URL or a SVG XML contents.\" % type(self).__name__)\n        super(SVG, self)._type_error(object)\n\n    def _img(self):\n        if (isinstance(self.object, string_types) and\n            self.object.lstrip().startswith('<svg')):\n            return self.object\n        return super(SVG, self)._img()\n\n    def _b64(self):\n        data = self._img()\n        if not isinstance(data, bytes):\n            data = data.encode('utf-8')\n        b64 = base64.b64encode(data).decode(\"utf-8\")\n        return f\"data:image/svg+xml;base64,{b64}\"\n\n    def _imgshape(self, data):\n        return (self.width, self.height)\n\n    def _get_properties(self):\n        p = super(ImageBase, self)._get_properties()\n        if self.object is None:\n            return dict(p, text='<img></img>')\n        data = self._img()\n        width, height = self._imgshape(data)\n        if not isinstance(data, bytes):\n            data = data.encode('utf-8')\n\n        if self.encode:\n            b64 = base64.b64encode(data).decode(\"utf-8\")\n            src = \"data:image/svg+xml;base64,{b64}\".format(b64=b64)\n            html = \"<img src='{src}' width={width} height={height}></img>\".format(\n                src=src, width=width, height=height\n            )\n        else:\n            html = data.decode(\"utf-8\")\n        return dict(p, width=width, height=height, text=escape(html))\n", "path": "panel/pane/image.py"}], "after_files": [{"content": "\"\"\"\nContains Image panes including renderers for PNG, SVG, GIF and JPG\nfile types.\n\"\"\"\nfrom __future__ import absolute_import, division, unicode_literals\n\nimport base64\n\nfrom io import BytesIO\nfrom six import string_types\n\nimport param\n\nfrom .markup import escape, DivPaneBase\nfrom ..util import isfile, isurl\n\n\nclass ImageBase(DivPaneBase):\n    \"\"\"\n    Encodes an image as base64 and wraps it in a Bokeh Div model.\n    This is an abstract base class that needs the image type\n    to be specified and specific code for determining the image shape.\n\n    The imgtype determines the filetype, extension, and MIME type for\n    this image. Each image type (png,jpg,gif) has a base class that\n    supports anything with a `_repr_X_` method (where X is `png`,\n    `gif`, etc.), a local file with the given file extension, or a\n    HTTP(S) url with the given extension.  Subclasses of each type can\n    provide their own way of obtaining or generating a PNG.\n    \"\"\"\n\n    alt_text = param.String(default=None, doc=\"\"\"\n        alt text to add to the image tag. The alt text is shown when a\n        user cannot load or display the image.\"\"\")\n\n    link_url = param.String(default=None, doc=\"\"\"\n        A link URL to make the image clickable and link to some other\n        website.\"\"\")\n\n    embed = param.Boolean(default=True, doc=\"\"\"\n        Whether to embed the image as base64.\"\"\")\n\n    imgtype = 'None'\n\n    _rerender_params = ['alt_text', 'link_url', 'embed', 'object', 'style']\n\n    _target_transforms = {'object': \"\"\"'<img src=\"' + value + '\"></img>'\"\"\"}\n\n    __abstract = True\n\n    @classmethod\n    def applies(cls, obj):\n        imgtype = cls.imgtype\n        if hasattr(obj, '_repr_{}_'.format(imgtype)):\n            return True\n        if isinstance(obj, string_types):\n            if isfile(obj) and obj.endswith('.'+imgtype):\n                return True\n            if isurl(obj, [cls.imgtype]):\n                return True\n            elif isurl(obj, None):\n                return 0\n        if hasattr(obj, 'read'):  # Check for file like object\n            return True\n        return False\n\n    def _type_error(self, object):\n        if isinstance(object, string_types):\n            raise ValueError(\"%s pane cannot parse string that is not a filename \"\n                             \"or URL.\" % type(self).__name__)\n        super(ImageBase, self)._type_error(object)\n\n    def _img(self):\n        if hasattr(self.object, '_repr_{}_'.format(self.imgtype)):\n            return getattr(self.object, '_repr_' + self.imgtype + '_')()\n        if isinstance(self.object, string_types):\n            if isfile(self.object):\n                with open(self.object, 'rb') as f:\n                    return f.read()\n        if hasattr(self.object, 'read'):\n            if hasattr(self.object, 'seek'):\n                self.object.seek(0)\n            return self.object.read()\n        if isurl(self.object, None):\n            import requests\n            r = requests.request(url=self.object, method='GET')\n            return r.content\n\n    def _b64(self):\n        data = self._img()\n        if not isinstance(data, bytes):\n            data = data.encode('utf-8')\n        b64 = base64.b64encode(data).decode(\"utf-8\")\n        return \"data:image/\"+self.imgtype+f\";base64,{b64}\"\n\n    def _imgshape(self, data):\n        \"\"\"Calculate and return image width,height\"\"\"\n        raise NotImplementedError\n\n    def _get_properties(self):\n        p = super(ImageBase, self)._get_properties()\n        if self.object is None:\n            return dict(p, text='<img></img>')\n        data = self._img()\n        if not isinstance(data, bytes):\n            data = base64.b64decode(data)\n        width, height = self._imgshape(data)\n        if self.width is not None:\n            if self.height is None:\n                height = int((self.width/width)*height)\n            else:\n                height = self.height\n            width = self.width\n        elif self.height is not None:\n            width = int((self.height/height)*width)\n            height = self.height\n        if not self.embed:\n            src = self.object\n        else:\n            b64 = base64.b64encode(data).decode(\"utf-8\")\n            src = \"data:image/\"+self.imgtype+\";base64,{b64}\".format(b64=b64)\n\n        smode = self.sizing_mode\n        if smode in ['fixed', None]:\n            w, h = '%spx' % width, '%spx' % height\n        elif smode == 'stretch_both':\n            w, h = '100%', '100%'\n        elif smode == 'stretch_width':\n            w, h = '%spx' % width, '100%'\n        elif smode == 'stretch_height':\n            w, h = '100%', '%spx' % height\n        elif smode == 'scale_height':\n            w, h = 'auto', '100%'\n        else:\n            w, h = '100%', 'auto'\n\n        html = '<img src=\"{src}\" width=\"{width}\" height=\"{height}\" alt=\"{alt}\"></img>'.format(\n            src=src, width=w, height=h, alt=self.alt_text or '')\n\n        if self.link_url:\n            html = '<a href=\"{url}\" target=\"_blank\">{html}</a>'.format(\n                url=self.link_url, html=html)\n\n        return dict(p, width=width, height=height, text=escape(html))\n\n\nclass PNG(ImageBase):\n\n    imgtype = 'png'\n\n    @classmethod\n    def _imgshape(cls, data):\n        import struct\n        w, h = struct.unpack('>LL', data[16:24])\n        return int(w), int(h)\n\n\nclass GIF(ImageBase):\n\n    imgtype = 'gif'\n\n    @classmethod\n    def _imgshape(cls, data):\n        import struct\n        w, h = struct.unpack(\"<HH\", data[6:10])\n        return int(w), int(h)\n\n\nclass JPG(ImageBase):\n\n    imgtype = 'jpg'\n\n    @classmethod\n    def _imgshape(cls, data):\n        import struct\n        b = BytesIO(data)\n        b.read(2)\n        c = b.read(1)\n        while (c and ord(c) != 0xDA):\n            while (ord(c) != 0xFF): c = b.read(1)\n            while (ord(c) == 0xFF): c = b.read(1)\n            if (ord(c) >= 0xC0 and ord(c) <= 0xC3):\n                b.read(3)\n                h, w = struct.unpack(\">HH\", b.read(4))\n                break\n            else:\n                b.read(int(struct.unpack(\">H\", b.read(2))[0])-2)\n            c = b.read(1)\n        return int(w), int(h)\n\n\nclass SVG(ImageBase):\n\n    encode = param.Boolean(default=False, doc=\"\"\"\n        Whether to enable base64 encoding of the SVG, base64 encoded\n        SVGs do not support links.\"\"\")\n\n    imgtype = 'svg'\n\n    _rerender_params = ImageBase._rerender_params + ['encode']\n\n    @classmethod\n    def applies(cls, obj):\n        return (super(SVG, cls).applies(obj) or\n                (isinstance(obj, string_types) and obj.lstrip().startswith('<svg')))\n\n    def _type_error(self, object):\n        if isinstance(object, string_types):\n            raise ValueError(\"%s pane cannot parse string that is not a filename, \"\n                             \"URL or a SVG XML contents.\" % type(self).__name__)\n        super(SVG, self)._type_error(object)\n\n    def _img(self):\n        if (isinstance(self.object, string_types) and\n            self.object.lstrip().startswith('<svg')):\n            return self.object\n        return super(SVG, self)._img()\n\n    def _b64(self):\n        data = self._img()\n        if not isinstance(data, bytes):\n            data = data.encode('utf-8')\n        b64 = base64.b64encode(data).decode(\"utf-8\")\n        return f\"data:image/svg+xml;base64,{b64}\"\n\n    def _imgshape(self, data):\n        return (self.width, self.height)\n\n    def _get_properties(self):\n        p = super(ImageBase, self)._get_properties()\n        if self.object is None:\n            return dict(p, text='<img></img>')\n        data = self._img()\n        width, height = self._imgshape(data)\n        if not isinstance(data, bytes):\n            data = data.encode('utf-8')\n\n        if self.encode:\n            b64 = base64.b64encode(data).decode(\"utf-8\")\n            src = \"data:image/svg+xml;base64,{b64}\".format(b64=b64)\n            html = \"<img src='{src}' width={width} height={height}></img>\".format(\n                src=src, width=width, height=height\n            )\n        else:\n            html = data.decode(\"utf-8\")\n        return dict(p, width=width, height=height, text=escape(html))\n", "path": "panel/pane/image.py"}]}