Repository: streamlit/streamlit

Issue:
OSError: cannot write mode P as JPEG
### Summary

When I upload a PNG image using `st.file_uploader` and try to display it, it throws an error because Streamlit doesn't seem to support displaying images with alpha channel.

### Steps to reproduce

```
# uploaded_img: PNG with 4 channels
st.image(uploaded_img)
```

You can use this image:  
https://www.researchgate.net/profile/Vk-Koppula-2/publication/224106740/figure/fig7/AS:670427986796555@1536853896257/a-Telugu-text-image.png

**Expected behavior:**

Either display the transparent image or drop the alpha-channel and display it as RGB.

**Actual behavior:**

```
OSError: cannot write mode P as JPEG
```

### Debug info

- Streamlit version: 0.85
- Python version: 3.7
- Using Conda? PipEnv? PyEnv? Pex? : Pip
- OS version: Ubuntu 18.04
- Browser version: Chrome 91

---

Edit: Seems to work well for other PNG files with transparency. So what could be issue?


Discussion:
Hey @GokulNC!

I think there may be something else going on here as I'm unable to reproduce the issue by calling `st.image` on the image you provided. Are you able to provide a minimal code snippet and repro case?

My attempt uses the following small script
```python
import streamlit as st

uploaded_img = st.file_uploader("upload an image")
if uploaded_img:
    st.image(uploaded_img)
```
Thanks. Looks like I wasn't precise enough.
Modified your snippet to reproduce the issue with that sample image:

```py
import streamlit as st

uploaded_img = st.file_uploader("upload an image")
if uploaded_img:
    st.image(uploaded_img, width=480)
```

That is, when I set the `width` explicitly, I face that error.
Thanks @GokulNC!

I'm now able to repro the issue, and I'll investigate further if I have the time to do so next week.

As far as I can tell from a quick glance at the code, it seems like we're somehow trying to display images uploaded to the `file_uploader` as a jpg when the `width` argument of `st.image` is set, so a workaround is to explicity specify that the output file type should be a png.

Writing
```python
st.image(uploaded_img, width=480, output_format="png")
```
avoids the bug for me.


Resolving patch:
diff --git a/lib/streamlit/elements/image.py b/lib/streamlit/elements/image.py
--- a/lib/streamlit/elements/image.py
+++ b/lib/streamlit/elements/image.py
@@ -134,10 +134,8 @@ def dg(self) -> "streamlit.delta_generator.DeltaGenerator":
         return cast("streamlit.delta_generator.DeltaGenerator", self)
 
 
-def _image_has_alpha_channel(image):
-    if image.mode in ("RGBA", "LA") or (
-        image.mode == "P" and "transparency" in image.info
-    ):
+def _image_may_have_alpha_channel(image):
+    if image.mode in ("RGBA", "LA", "P"):
         return True
     else:
         return False
@@ -152,7 +150,7 @@ def _format_from_image_type(image, output_format):
     if output_format == "JPG":
         return "JPEG"
 
-    if _image_has_alpha_channel(image):
+    if _image_may_have_alpha_channel(image):
         return "PNG"
 
     return "JPEG"
@@ -162,7 +160,7 @@ def _PIL_to_bytes(image, format="JPEG", quality=100):
     tmp = io.BytesIO()
 
     # User must have specified JPEG, so we must convert it
-    if format == "JPEG" and _image_has_alpha_channel(image):
+    if format == "JPEG" and _image_may_have_alpha_channel(image):
         image = image.convert("RGB")
 
     image.save(tmp, format=format, quality=quality)


Test patch:
diff --git a/lib/tests/streamlit/image_test.py b/lib/tests/streamlit/image_test.py
--- a/lib/tests/streamlit/image_test.py
+++ b/lib/tests/streamlit/image_test.py
@@ -280,3 +280,8 @@ def test_clip_image(self):
         * int  with clipping
         """
         pass
+
+    @parameterized.expand([("P", True), ("RGBA", True), ("LA", True), ("RGB", False)])
+    def test_image_may_have_alpha_channel(self, format: str, expected_alpha: bool):
+        img = Image.new(format, (1, 1))
+        self.assertEqual(image._image_may_have_alpha_channel(img), expected_alpha)