Improving performance for faster results: since many images have a black or white border, do you expect faster completion by selecting a few random i, j points from im and testing them? Or use modulo arithmetic to move lines of the image. First, we trace (without replacement) 100 random i, j-points; in the unlikely event this is not final, then we scan it linearly.
Using the iterpixels custom iterator (im). I do not have PIL, so I can not check this, here is the diagram:
import Image def isColor(r,g,b): # use tuple-unpacking to unpack pixel -> r,g,b return (r != g != b) class Image_(Image): def __init__(pathname): self.im = Image.open(pathname) self.w, self.h = self.im.size def iterpixels(nrand=100, randseed=None): if randseed: random.seed(randseed) # For deterministic behavior in test # First, generate a few random pixels from entire image for randpix in random.choice(im, n_rand) yield randpix # Now traverse entire image (yes we will unwantedly revisit the nrand points once) #for pixel in im.getpixel(...): # you could traverse rows linearly, or modulo (say) (im.height * 2./3) -1 # yield pixel def is_grey_scale(img_path="lena.jpg"): im = Image_.(img_path) return (any(isColor(*pixel)) for pixel in im.iterpixels())
(Also, my original point is, first you check the JPEG header, offset 6: number of components (1 = grayscale, 3 = RGB). If it's 1 = grayscale, you already know the answer without having to check individual pixels.)
smci
source share