The easiest way is to use the `numpy` interface for this, since it allows you to do operations on the whole image: from PIL import Image import numpy as np def _colour_mask(img, colour): """Finds all indices of a single colour in a PIL.Image""" return (img == colour).all(axis=2).nonzero() def _convert_colour(img, incolour, outcolour): """Replaces incolour with outcolour in a PIL.Image. Returns a new PIL.Image. Assumes that img has as many channels as len(incolour) and len(outcolour). """ img = np.array(img) img[_colour_mask(incolour)] = outcolour return Image.fromarray(img) def convert_colour(region_number, incolour, outcolour): file_name = region_list.regions_d[region_number][0] img = Image.open(file_name) new_img = _convert_colour(img, incolour, outcolour) new_img.save(file_name, "PNG")