Skip to content

Instantly share code, notes, and snippets.

@SHi-ON
Last active September 17, 2023 16:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save SHi-ON/bd929d8575a8997b26dee3b498e90b16 to your computer and use it in GitHub Desktop.
Save SHi-ON/bd929d8575a8997b26dee3b498e90b16 to your computer and use it in GitHub Desktop.
Replace colors in a given PDF file. The original goal was to print a PDF paper using a printer with no black cartridge!
import concurrent.futures
import itertools
import math
import pdf2image # $ brew install poppler
from tqdm import tqdm
BLACK = (0, 0, 0)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
RGB = [RED, GREEN, BLUE]
THRESHOLD = 100
DPI = 1200 # Larger file size in exchange for higher print quality
def color_distance(color1, color2):
r1, g1, b1 = color1
r2, g2, b2 = color2
distance = math.sqrt((r2 - r1) ** 2 + (g2 - g1) ** 2 + (b2 - b1) ** 2)
return distance
def is_color_close(color1, color2, threshold=THRESHOLD):
distance = color_distance(color1, color2)
return distance < threshold
def is_gray_shade(color):
r, g, b = color
return r == g == b and (r, g, b) != (255, 255, 255)
def replace_color(image, source_color, destination_color):
pixels = image.load() # reference to the original Image object pixels
for i, j in itertools.product(range(image.size[0]),
range(image.size[1])):
rgb = pixels[i, j]
if is_gray_shade(rgb):
pixels[i, j] = destination_color
def replace_iteratively(images):
for i, image in tqdm(enumerate(images), total=len(images)):
replace_color(image, BLACK, RGB[i % 3])
# image.show()
return images
def replace_worker(args):
index, image = args
replace_color(image, BLACK, RGB[index % 3])
return image
def replace_concurrently(images):
with concurrent.futures.ProcessPoolExecutor() as executor:
images = list(tqdm(
iterable=executor.map(replace_worker, enumerate(images)),
total=len(images)
))
return images
def main():
images = pdf2image.convert_from_path('Input.pdf', dpi=DPI)
images = replace_concurrently(images)
images[0].save('Output.pdf', save_all=True, append_images=images[1:])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment