diff --git a/README.md b/README.md new file mode 100644 index 0000000..b392365 --- /dev/null +++ b/README.md @@ -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. \ No newline at end of file diff --git a/README.rst b/README.rst deleted file mode 100644 index 3da0123..0000000 --- a/README.rst +++ /dev/null @@ -1,9 +0,0 @@ -qwer -==== - -Floyd-Steinberg dithering in python - -Usage ------ - -``qwer lena.bmp -o lena.png`` diff --git a/examples/david_crop-bw.png b/examples/david_crop-bw.png new file mode 100644 index 0000000..d23e369 Binary files /dev/null and b/examples/david_crop-bw.png differ diff --git a/examples/david_crop-colour.png b/examples/david_crop-colour.png new file mode 100644 index 0000000..b4b1ba9 Binary files /dev/null and b/examples/david_crop-colour.png differ diff --git a/examples/david_crop.png b/examples/david_crop.png new file mode 100644 index 0000000..4c347e6 Binary files /dev/null and b/examples/david_crop.png differ diff --git a/main.py b/main.py index 3eab89a..232be42 100644 --- a/main.py +++ b/main.py @@ -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 @@ -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): @@ -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() @@ -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() \ No newline at end of file