Repository: python-pillow/Pillow

Problem statement:
Mix use of grayscale/greyscale in document and code
<!--
Thank you for reporting an issue.

Follow these guidelines to ensure your issue is handled properly.

If you have a ...

1.  General question: consider asking the question on Stack Overflow
    with the python-imaging-library tag:

    * https://stackoverflow.com/questions/tagged/python-imaging-library

    Do not ask a question in both places.

    If you think you have found a bug or have an unexplained exception
    then file a bug report here.

2.  Bug report: include a self-contained, copy-pastable example that
    generates the issue if possible. Be concise with code posted.
    Guidelines on how to provide a good bug report:

    * https://stackoverflow.com/help/mcve

    Bug reports which follow these guidelines are easier to diagnose,
    and are often handled much more quickly.

3.  Feature request: do a quick search of existing issues
    to make sure this has not been asked before.

We know asking good questions takes effort, and we appreciate your time.
Thank you.
-->

### What did you do?

I've been searching in the document and found it use "grayscale" in some places and "greyscale" in some other places, describing same type of images in Pillow. I also viewed those parts of code and found out they are mostly consistent with corresponding documents.

### What did you expect to happen?
It should be using the same word across the whole document and code.

### What actually happened?
Mix use of slightly different spelling words across multiple places.

### What are your OS, Python and Pillow versions?
Not related to the issue. The mix use of both words seems to have been the case for a very long time, at least since Pillow 3.x, which makes me a bit confused.


### Examples

#### Examples of grayscale:
* `L` (8-bit pixels, grayscale) [[Modes](https://pillow.readthedocs.io/en/stable/handbook/concepts.html#concept-modes)]
* GIF files are initially read as grayscale (L) or palette mode (P) images. [[GIF](https://pillow.readthedocs.io/en/stable/handbook/image-file-formats.html#gif)]
* [[`PIL.ImageOps.grayscale(image)`](https://pillow.readthedocs.io/en/stable/reference/ImageOps.html#PIL.ImageOps.grayscale)]

#### Examples of greyscale:

* When translating a color image to greyscale (mode “L”) [[`Image.convert(mode=None, matrix=None, dither=None, palette=Palette.WEB, colors=256)`](https://pillow.readthedocs.io/en/stable/reference/Image.html#PIL.Image.Image.convert)]
* A bilevel image (mode “1”) is treated as a greyscale (“L”) image by this method. [[`Image.histogram(mask=None, extrema=None)`](https://pillow.readthedocs.io/en/stable/reference/Image.html#PIL.Image.Image.histogram),[`Image.entropy(mask=None, extrema=None)`](https://pillow.readthedocs.io/en/stable/reference/Image.html#PIL.Image.Image.entropy)]
* Parameters: threshold – All pixels above this greyscale level are inverted. [[`PIL.ImageOps.solarize(image, threshold=128)`](https://pillow.readthedocs.io/en/stable/reference/ImageOps.html#PIL.ImageOps.solarize)]


Hints:

Patch:
diff --git a/src/PIL/BmpImagePlugin.py b/src/PIL/BmpImagePlugin.py
--- a/src/PIL/BmpImagePlugin.py
+++ b/src/PIL/BmpImagePlugin.py
@@ -230,21 +230,21 @@ def _bitmap(self, header=0, offset=0):
             else:
                 padding = file_info["palette_padding"]
                 palette = read(padding * file_info["colors"])
-                greyscale = True
+                grayscale = True
                 indices = (
                     (0, 255)
                     if file_info["colors"] == 2
                     else list(range(file_info["colors"]))
                 )
 
-                # ----------------- Check if greyscale and ignore palette if so
+                # ----------------- Check if grayscale and ignore palette if so
                 for ind, val in enumerate(indices):
                     rgb = palette[ind * padding : ind * padding + 3]
                     if rgb != o8(val) * 3:
-                        greyscale = False
+                        grayscale = False
 
-                # ------- If all colors are grey, white or black, ditch palette
-                if greyscale:
+                # ------- If all colors are gray, white or black, ditch palette
+                if grayscale:
                     self._mode = "1" if file_info["colors"] == 2 else "L"
                     raw_mode = self.mode
                 else:
diff --git a/src/PIL/Image.py b/src/PIL/Image.py
--- a/src/PIL/Image.py
+++ b/src/PIL/Image.py
@@ -878,12 +878,12 @@ def convert(
         "L", "RGB" and "CMYK". The ``matrix`` argument only supports "L"
         and "RGB".
 
-        When translating a color image to greyscale (mode "L"),
+        When translating a color image to grayscale (mode "L"),
         the library uses the ITU-R 601-2 luma transform::
 
             L = R * 299/1000 + G * 587/1000 + B * 114/1000
 
-        The default method of converting a greyscale ("L") or "RGB"
+        The default method of converting a grayscale ("L") or "RGB"
         image into a bilevel (mode "1") image uses Floyd-Steinberg
         dither to approximate the original image luminosity levels. If
         dither is ``None``, all values larger than 127 are set to 255 (white),
@@ -1238,7 +1238,7 @@ def draft(self, mode, size):
         Configures the image file loader so it returns a version of the
         image that as closely as possible matches the given mode and
         size. For example, you can use this method to convert a color
-        JPEG to greyscale while loading it.
+        JPEG to grayscale while loading it.
 
         If any changes are made, returns a tuple with the chosen ``mode`` and
         ``box`` with coordinates of the original image within the altered one.
@@ -1610,13 +1610,13 @@ def histogram(self, mask=None, extrema=None):
         than one band, the histograms for all bands are concatenated (for
         example, the histogram for an "RGB" image contains 768 values).
 
-        A bilevel image (mode "1") is treated as a greyscale ("L") image
+        A bilevel image (mode "1") is treated as a grayscale ("L") image
         by this method.
 
         If a mask is provided, the method returns a histogram for those
         parts of the image where the mask image is non-zero. The mask
         image must have the same size as the image, and be either a
-        bi-level image (mode "1") or a greyscale image ("L").
+        bi-level image (mode "1") or a grayscale image ("L").
 
         :param mask: An optional mask.
         :param extrema: An optional tuple of manually-specified extrema.
@@ -1636,13 +1636,13 @@ def entropy(self, mask=None, extrema=None):
         """
         Calculates and returns the entropy for the image.
 
-        A bilevel image (mode "1") is treated as a greyscale ("L")
+        A bilevel image (mode "1") is treated as a grayscale ("L")
         image by this method.
 
         If a mask is provided, the method employs the histogram for
         those parts of the image where the mask image is non-zero.
         The mask image must have the same size as the image, and be
-        either a bi-level image (mode "1") or a greyscale image ("L").
+        either a bi-level image (mode "1") or a grayscale image ("L").
 
         :param mask: An optional mask.
         :param extrema: An optional tuple of manually-specified extrema.
@@ -2876,7 +2876,7 @@ class ImageTransformHandler:
 
 
 def _wedge():
-    """Create greyscale wedge (for debugging only)"""
+    """Create grayscale wedge (for debugging only)"""
 
     return Image()._new(core.wedge("L"))
 
diff --git a/src/PIL/ImageChops.py b/src/PIL/ImageChops.py
--- a/src/PIL/ImageChops.py
+++ b/src/PIL/ImageChops.py
@@ -19,7 +19,7 @@
 
 
 def constant(image, value):
-    """Fill a channel with a given grey level.
+    """Fill a channel with a given gray level.
 
     :rtype: :py:class:`~PIL.Image.Image`
     """
diff --git a/src/PIL/ImageColor.py b/src/PIL/ImageColor.py
--- a/src/PIL/ImageColor.py
+++ b/src/PIL/ImageColor.py
@@ -124,7 +124,7 @@ def getcolor(color, mode):
     """
     Same as :py:func:`~PIL.ImageColor.getrgb` for most modes. However, if
     ``mode`` is HSV, converts the RGB value to a HSV value, or if ``mode`` is
-    not color or a palette image, converts the RGB value to a greyscale value.
+    not color or a palette image, converts the RGB value to a grayscale value.
     If the string cannot be parsed, this function raises a :py:exc:`ValueError`
     exception.
 
diff --git a/src/PIL/ImageEnhance.py b/src/PIL/ImageEnhance.py
--- a/src/PIL/ImageEnhance.py
+++ b/src/PIL/ImageEnhance.py
@@ -59,7 +59,7 @@ class Contrast(_Enhance):
 
     This class can be used to control the contrast of an image, similar
     to the contrast control on a TV set. An enhancement factor of 0.0
-    gives a solid grey image. A factor of 1.0 gives the original image.
+    gives a solid gray image. A factor of 1.0 gives the original image.
     """
 
     def __init__(self, image):
diff --git a/src/PIL/ImageOps.py b/src/PIL/ImageOps.py
--- a/src/PIL/ImageOps.py
+++ b/src/PIL/ImageOps.py
@@ -593,7 +593,7 @@ def solarize(image, threshold=128):
     Invert all pixel values above a threshold.
 
     :param image: The image to solarize.
-    :param threshold: All pixels above this greyscale level are inverted.
+    :param threshold: All pixels above this grayscale level are inverted.
     :return: An image.
     """
     lut = []
diff --git a/src/PIL/ImageWin.py b/src/PIL/ImageWin.py
--- a/src/PIL/ImageWin.py
+++ b/src/PIL/ImageWin.py
@@ -54,9 +54,9 @@ class Dib:
     "L", "P", or "RGB".
 
     If the display requires a palette, this constructor creates a suitable
-    palette and associates it with the image. For an "L" image, 128 greylevels
+    palette and associates it with the image. For an "L" image, 128 graylevels
     are allocated. For an "RGB" image, a 6x6x6 colour cube is used, together
-    with 20 greylevels.
+    with 20 graylevels.
 
     To make sure that palettes work properly under Windows, you must call the
     ``palette`` method upon certain events from Windows.
diff --git a/src/PIL/PSDraw.py b/src/PIL/PSDraw.py
--- a/src/PIL/PSDraw.py
+++ b/src/PIL/PSDraw.py
@@ -109,7 +109,7 @@ def image(self, box, im, dpi=None):
             if im.mode == "1":
                 dpi = 200  # fax
             else:
-                dpi = 100  # greyscale
+                dpi = 100  # grayscale
         # image size (on paper)
         x = im.size[0] * 72 / dpi
         y = im.size[1] * 72 / dpi
diff --git a/src/PIL/PalmImagePlugin.py b/src/PIL/PalmImagePlugin.py
--- a/src/PIL/PalmImagePlugin.py
+++ b/src/PIL/PalmImagePlugin.py
@@ -124,7 +124,7 @@ def _save(im, fp, filename):
         if im.encoderinfo.get("bpp") in (1, 2, 4):
             # this is 8-bit grayscale, so we shift it to get the high-order bits,
             # and invert it because
-            # Palm does greyscale from white (0) to black (1)
+            # Palm does grayscale from white (0) to black (1)
             bpp = im.encoderinfo["bpp"]
             im = im.point(
                 lambda x, shift=8 - bpp, maxval=(1 << bpp) - 1: maxval - (x >> shift)
diff --git a/src/PIL/PcxImagePlugin.py b/src/PIL/PcxImagePlugin.py
--- a/src/PIL/PcxImagePlugin.py
+++ b/src/PIL/PcxImagePlugin.py
@@ -91,7 +91,7 @@ def _open(self):
             self.fp.seek(-769, io.SEEK_END)
             s = self.fp.read(769)
             if len(s) == 769 and s[0] == 12:
-                # check if the palette is linear greyscale
+                # check if the palette is linear grayscale
                 for i in range(256):
                     if s[i * 3 + 1 : i * 3 + 4] != o8(i) * 3:
                         mode = rawmode = "P"
@@ -203,7 +203,7 @@ def _save(im, fp, filename):
         palette += b"\x00" * (768 - len(palette))
         fp.write(palette)  # 768 bytes
     elif im.mode == "L":
-        # greyscale palette
+        # grayscale palette
         fp.write(o8(12))
         for i in range(256):
             fp.write(o8(i) * 3)
diff --git a/src/PIL/PngImagePlugin.py b/src/PIL/PngImagePlugin.py
--- a/src/PIL/PngImagePlugin.py
+++ b/src/PIL/PngImagePlugin.py
@@ -56,7 +56,7 @@
 
 _MODES = {
     # supported bits/color combinations, and corresponding modes/rawmodes
-    # Greyscale
+    # Grayscale
     (1, 0): ("1", "1"),
     (2, 0): ("L", "L;2"),
     (4, 0): ("L", "L;4"),
@@ -70,7 +70,7 @@
     (2, 3): ("P", "P;2"),
     (4, 3): ("P", "P;4"),
     (8, 3): ("P", "P"),
-    # Greyscale with alpha
+    # Grayscale with alpha
     (8, 4): ("LA", "LA"),
     (16, 4): ("RGBA", "LA;16B"),  # LA;16B->LA not yet available
     # Truecolour with alpha


Test patch:
diff --git a/Tests/images/apng/mode_greyscale.png b/Tests/images/apng/mode_grayscale.png
similarity index 100%
rename from Tests/images/apng/mode_greyscale.png
rename to Tests/images/apng/mode_grayscale.png
diff --git a/Tests/images/apng/mode_greyscale_alpha.png b/Tests/images/apng/mode_grayscale_alpha.png
similarity index 100%
rename from Tests/images/apng/mode_greyscale_alpha.png
rename to Tests/images/apng/mode_grayscale_alpha.png
diff --git a/Tests/images/hopper_rle8_greyscale.bmp b/Tests/images/hopper_rle8_grayscale.bmp
similarity index 100%
rename from Tests/images/hopper_rle8_greyscale.bmp
rename to Tests/images/hopper_rle8_grayscale.bmp
diff --git a/Tests/test_file_apng.py b/Tests/test_file_apng.py
--- a/Tests/test_file_apng.py
+++ b/Tests/test_file_apng.py
@@ -231,13 +231,13 @@ def test_apng_mode():
         assert im.getpixel((0, 0)) == (0, 0, 128, 191)
         assert im.getpixel((64, 32)) == (0, 0, 128, 191)
 
-    with Image.open("Tests/images/apng/mode_greyscale.png") as im:
+    with Image.open("Tests/images/apng/mode_grayscale.png") as im:
         assert im.mode == "L"
         im.seek(im.n_frames - 1)
         assert im.getpixel((0, 0)) == 128
         assert im.getpixel((64, 32)) == 255
 
-    with Image.open("Tests/images/apng/mode_greyscale_alpha.png") as im:
+    with Image.open("Tests/images/apng/mode_grayscale_alpha.png") as im:
         assert im.mode == "LA"
         im.seek(im.n_frames - 1)
         assert im.getpixel((0, 0)) == (128, 191)
diff --git a/Tests/test_file_bmp.py b/Tests/test_file_bmp.py
--- a/Tests/test_file_bmp.py
+++ b/Tests/test_file_bmp.py
@@ -159,7 +159,7 @@ def test_rle8():
     with Image.open("Tests/images/hopper_rle8.bmp") as im:
         assert_image_similar_tofile(im.convert("RGB"), "Tests/images/hopper.bmp", 12)
 
-    with Image.open("Tests/images/hopper_rle8_greyscale.bmp") as im:
+    with Image.open("Tests/images/hopper_rle8_grayscale.bmp") as im:
         assert_image_equal_tofile(im, "Tests/images/bw_gradient.png")
 
     # This test image has been manually hexedited
diff --git a/Tests/test_file_gif.py b/Tests/test_file_gif.py
--- a/Tests/test_file_gif.py
+++ b/Tests/test_file_gif.py
@@ -590,7 +590,7 @@ def test_save_dispose(tmp_path):
 def test_dispose2_palette(tmp_path):
     out = str(tmp_path / "temp.gif")
 
-    # Four colors: white, grey, black, red
+    # Four colors: white, gray, black, red
     circles = [(255, 255, 255), (153, 153, 153), (0, 0, 0), (255, 0, 0)]
 
     im_list = []
diff --git a/Tests/test_file_png.py b/Tests/test_file_png.py
--- a/Tests/test_file_png.py
+++ b/Tests/test_file_png.py
@@ -297,7 +297,7 @@ def test_save_p_transparent_black(self, tmp_path):
         assert_image(im, "RGBA", (10, 10))
         assert im.getcolors() == [(100, (0, 0, 0, 0))]
 
-    def test_save_greyscale_transparency(self, tmp_path):
+    def test_save_grayscale_transparency(self, tmp_path):
         for mode, num_transparent in {"1": 1994, "L": 559, "I": 559}.items():
             in_file = "Tests/images/" + mode.lower() + "_trns.png"
             with Image.open(in_file) as im:
diff --git a/Tests/test_imagechops.py b/Tests/test_imagechops.py
--- a/Tests/test_imagechops.py
+++ b/Tests/test_imagechops.py
@@ -10,7 +10,7 @@
 ORANGE = (255, 128, 0)
 WHITE = (255, 255, 255)
 
-GREY = 128
+GRAY = 128
 
 
 def test_sanity():
@@ -121,12 +121,12 @@ def test_constant():
     im = Image.new("RGB", (20, 10))
 
     # Act
-    new = ImageChops.constant(im, GREY)
+    new = ImageChops.constant(im, GRAY)
 
     # Assert
     assert new.size == im.size
-    assert new.getpixel((0, 0)) == GREY
-    assert new.getpixel((19, 9)) == GREY
+    assert new.getpixel((0, 0)) == GRAY
+    assert new.getpixel((19, 9)) == GRAY
 
 
 def test_darker_image():
diff --git a/Tests/test_imagefont.py b/Tests/test_imagefont.py
--- a/Tests/test_imagefont.py
+++ b/Tests/test_imagefont.py
@@ -303,8 +303,8 @@ def test_multiline_spacing(font):
     "orientation", (Image.Transpose.ROTATE_90, Image.Transpose.ROTATE_270)
 )
 def test_rotated_transposed_font(font, orientation):
-    img_grey = Image.new("L", (100, 100))
-    draw = ImageDraw.Draw(img_grey)
+    img_gray = Image.new("L", (100, 100))
+    draw = ImageDraw.Draw(img_gray)
     word = "testing"
 
     transposed_font = ImageFont.TransposedFont(font, orientation=orientation)
@@ -344,8 +344,8 @@ def test_rotated_transposed_font(font, orientation):
     ),
 )
 def test_unrotated_transposed_font(font, orientation):
-    img_grey = Image.new("L", (100, 100))
-    draw = ImageDraw.Draw(img_grey)
+    img_gray = Image.new("L", (100, 100))
+    draw = ImageDraw.Draw(img_gray)
     word = "testing"
 
     transposed_font = ImageFont.TransposedFont(font, orientation=orientation)