Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# qwer

This script accomplishes [Floyd-Steinberg dithering](https://en.wikipedia.org/wiki/Floyd%E2%80%93Steinberg_dithering) in Python. Takes inputs as bitmap or png files.

It is extremely useful for compression, especially the 1-bit ``--bw`` mode. In testing, this script in black and white mode was able to reduce 181x215 pixel image from 53.2KB to 4.89KB, albeit with all colour lost. Colour (default) mode reduced the image to 23.7KB.

## Usage

To use the script in colour, write as follows: ``python main.py lena.bmp -o lena.png``

If you wish to use the script in black and white: ``python main.py -o lena.png --bw``

## Creds

This script was originally created by [trimailov](https://github.com/trimailov). [lesageethan](https://github.com/lesageethan) added the 1-bit mode and transparency support.
9 changes: 0 additions & 9 deletions README.rst

This file was deleted.

Binary file added examples/david_crop-bw.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added examples/david_crop-colour.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added examples/david_crop.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
26 changes: 19 additions & 7 deletions main.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@


class Dither():
def __init__(self, path, algorithm=None, output=None):
def __init__(self, path, algorithm=None, output=None, bw=False):
self.bw = bw
self.path = self.get_path(path)
self.algorithm = algorithm
self.output = output
Expand Down Expand Up @@ -54,11 +55,19 @@ def floyd_steinberg_dither(self, image_file):
find_closest_palette_color(oldpixel) = floor(oldpixel / 256)
"""

new_img = Image.open(image_file)
new_img = Image.open(image_file).convert('RGBA')

# Turn transparent pixels white
background = Image.new("RGBA", new_img.size, "WHITE")
background.paste(new_img, mask=new_img)

# Convert to black and white if instructed
if self.bw:
new_img = new_img.convert('L')

new_img = new_img.convert('RGB')
pixel = new_img.load()

pixel = new_img.load()
x_lim, y_lim = new_img.size

for y in range(1, y_lim):
Expand Down Expand Up @@ -104,6 +113,9 @@ def floyd_steinberg_dither(self, image_file):
pixel[x+1, y+1] = (red, green, blue)

if self.output:
# Set colour to 1-bit if black and white is true
if self.bw:
new_img = new_img.convert("1")
new_img.save(self.output)
else:
new_img.show()
Expand All @@ -113,9 +125,9 @@ def main():
parser = ArgumentParser(description="Image dithering in python")
parser.add_argument("image_path", help="input image location")
parser.add_argument("-o", help="output image location")
parser.add_argument("--bw", help="black and white", action="store_true")
args = parser.parse_args()

if args.image_path and not args.o:
Dither(args.image_path)
elif args.image_path and args.o:
Dither(args.image_path, output=args.o)
Dither(args.image_path, output=args.o, bw=args.bw)

main()