Repository: python-pillow/Pillow

Issue:
Windows: image with alpha is not displayed correctly
### What did you do?
The pillow package has a method called [`Image.putalpha()`](https://pillow.readthedocs.io/en/stable/reference/Image.html#PIL.Image.Image.putalpha) which is used to add or change the alpha channel of an image.

I tried to play with this method and found that I can not change the background color of an image. The original image is

![owl](https://user-images.githubusercontent.com/16662357/53881897-d0221780-404f-11e9-9550-e53ecfa057f8.jpg)

This is my code to add alpha to it

```python
from PIL import Image

im_owl = Image.open("owl.jpg")

alpha = Image.new("L", im_owl.size, 50)
im_owl.putalpha(alpha)

im_owl.show()
```
### What did you expect to happen?
The produced image shows the effect of adding alpha channel to image.

### What actually happened?

The produced image is nothing different from the original image. I have tried with different value of alpha and see no difference.

### What are your OS, Python and Pillow versions?

* OS:  Windows 10 1803
* Python:  3.6.5
* Pillow: 5.3.0

After consulting the  pillow doc about `Image.show()` method, it seems that pillow will convert the Image object to bmp files and show it with default system image viewer.  That explains the reason why no difference between the original and alpha-composited image.

It would be great if the image is shown as its original format, not as bmp files. 


Discussion:
Yep, the docs say:

> ### `Image.show(title=None, command=None)`
>
> Displays this image. This method is mainly intended for debugging purposes.
> 
> On Unix platforms, this method saves the image to a temporary PPM file, and calls either the **xv** utility or the **display** utility, depending on which one can be found.
> 
> On macOS, this method saves the image to a temporary BMP file, and opens it with the native Preview application.
> 
> On Windows, it saves the image to a temporary BMP file, and uses the standard BMP display utility to show it (usually Paint).

https://pillow.readthedocs.io/en/stable/reference/Image.html#PIL.Image.Image.show

Note "method is mainly intended for debugging purposes".

You can save the image first and then use the viewer of your choice to open it.

Alternatively, it's possible to override it to use your own choice of viewer. See [ImageShow.py](https://github.com/python-pillow/Pillow/blob/master/src/PIL/ImageShow.py) and:

https://github.com/python-pillow/Pillow/blob/81946775166e0331f53ab130741683f0153e2ad1/src/PIL/Image.py#L2899-L2909


Perhaps a `WindowsPngViewer` with `format = "PNG"` would work (maybe subclass `WindowsViewer`), and then `register(WindowsPngViewer, -1)`? I don't have a Windows machine handy to test.
On Mac, I think the problem is the same. If the mode the Image object is `RGBA`, it should be displayed as PNG format, not as BMP format. It would be great to add that option to correctly display RGBA image. 

If it can not be done, at least there should be a warning that the displayed image is not a faithful representation of the true image. It really took me a while to figure out the problem is that the displayed image is not the same as the true image.
Actually, Mac switched from BMP to PNG in https://github.com/python-pillow/Pillow/pull/2527 and we've not updated the `Image.py` docstring yet (I've made https://github.com/python-pillow/Pillow/pull/3696 for that).

Perhaps we could default to PNG with Windows too. We'd need to make sure (1) we can save everything as PNG, or if not, save as BMP, and (2) this command works:

`'start "Pillow" /WAIT "%s" '`

`"Pillow"` is not a built-in viewer, it's a required title:

```
Syntax
      START "title" [/D path] [options] "command" [parameters]

Key:
   title       Text for the CMD window title bar (required.)
   path        Starting directory.
   command     The command, batch file or executable program to run.
   parameters  The parameters passed to the command.
```
https://ss64.com/nt/start.html

It just tells Windows to open an image file by giving the path to the file, and it'll open it in whatever program is associated with that file type. Usually IrfanView on my Windows machine, but we need it in a format that will open in something default like MS Paint (is that the default option?).

A quick look at https://en.wikipedia.org/wiki/List_of_Microsoft_Windows_versions shows Windows 7, 8.1 and 10 are still supported PC versions. I don't know if we need to worry about Windows Server when it comes to showing images.

It works. I add the following code after `register(WindowsViewer)` in the file `ImageShow.py`:

```python
    class WindowsPNGViewer(Viewer):
        format = "PNG"

        def get_command(self, file, **options):
            return ('start "Pillow" /WAIT "%s" '
                    '&& ping -n 2 127.0.0.1 >NUL '
                    '&& del /f "%s"' % (file, file))

    register(WindowsPNGViewer, -1)
```

After that, I can show the image with alpha channel correctly.
End users should also be able to switch to PNG through -

```python
from PIL import Image, ImageShow
ImageShow.WindowsViewer.format = "PNG"

im_owl = Image.open("owl.jpg")
im_owl.show()
```

Testing, I find that both BMP and PNG can save - 1, L, P, PA, F, RGB, RGBA, RGBX, CMYK, YCbCr - while PNG can save some modes that BMP can't - for example, LA and I. So I don't think we need to worry about using BMP as a fallback for certain image modes.

Resolving patch:
diff --git a/src/PIL/Image.py b/src/PIL/Image.py
--- a/src/PIL/Image.py
+++ b/src/PIL/Image.py
@@ -2110,15 +2110,15 @@ def show(self, title=None, command=None):
         Displays this image. This method is mainly intended for
         debugging purposes.
 
-        On Unix platforms, this method saves the image to a temporary
-        PNG file, and calls the **display**, **eog** or **xv**
-        utility, depending on which one can be found.
+        The image is first saved to a temporary file. By default, it will be in
+        PNG format.
 
-        On macOS, this method saves the image to a temporary PNG file, and
-        opens it with the native Preview application.
+        On Unix, the image is then opened using the **display**, **eog** or
+        **xv** utility, depending on which one can be found.
 
-        On Windows, it saves the image to a temporary BMP file, and uses
-        the standard BMP display utility to show it (usually Paint).
+        On macOS, the image is opened with the native Preview application.
+
+        On Windows, the image is opened with the standard PNG display utility.
 
         :param title: Optional title to use for the image window,
            where possible.
diff --git a/src/PIL/ImageShow.py b/src/PIL/ImageShow.py
--- a/src/PIL/ImageShow.py
+++ b/src/PIL/ImageShow.py
@@ -105,7 +105,8 @@ def show_file(self, file, **options):
 if sys.platform == "win32":
 
     class WindowsViewer(Viewer):
-        format = "BMP"
+        format = "PNG"
+        options = {"compress_level": 1}
 
         def get_command(self, file, **options):
             return (


Test patch: