3

I need to remove all white-spaces from image but I don't know how to do it.. I am using trim functionality to trim white spaces from border but still white-spaces are present in middle of image I am attaching my original image from which I want to remove white-spaces

original Image

my code

from PIL import Image, ImageChops
import numpy


def trim(im):
    bg = Image.new(im.mode, im.size, im.getpixel((0, 0)))
    diff = ImageChops.difference(im, bg)
    diff = ImageChops.add(diff, diff, 2.0, -100)
    box = diff.getbbox()
    if box:
        im.crop(box).save("trim_pil.png")


im = Image.open("/home/einfochips/Documents/imagecomparsion/kroger_image_comparison/SnapshotImages/screenshot_Hide.png")
im = trim(im)

but this code only remove space from borders, I need to remove spaces from middle also. Please help if possible, it would be very good if I got all five images in different PNG file.

Poorna Senani Gamage
  • 1,246
  • 2
  • 19
  • 30
Sachhya
  • 1,260
  • 1
  • 9
  • 16

1 Answers1

5

You could go the long way with a for loop

from PIL import Image, ImageChops

def getbox(im, color):
    bg = Image.new(im.mode, im.size, color)
    diff = ImageChops.difference(im, bg)
    diff = ImageChops.add(diff, diff, 2.0, -100)
    return diff.getbbox()

def split(im):
    retur = []
    emptyColor = im.getpixel((0, 0))
    box = getbox(im, emptyColor)
    width, height = im.size
    pixels = im.getdata()
    sub_start = 0
    sub_width = 0
    offset = box[1] * width
    for x in range(width):
        if pixels[x + offset] == emptyColor:
            if sub_width > 0:
                retur.append((sub_start, box[1], sub_width, box[3]))
                sub_width = 0
            sub_start = x + 1
        else:
            sub_width = x + 1
    if sub_width > 0:
        retur.append((sub_start, box[1], sub_width, box[3]))
    return retur

This makes it easy to retrieve the crop boxes in the image like this:

im = Image.open("/home/einfochips/Documents/imagecomparsion/kroger_image_comparison/SnapshotImages/screenshot_Hide.png")

for idx, box in enumerate(split(im)):
    im.crop(box).save("trim_{0}.png".format(idx))

If you already know the size of the images toy want to extract you could go with

def split(im, box):
    retur = []
    pixels = im.getdata()
    emptyColor = pixels[0]
    width, height = im.size;
    y = 0;
    while y < height - box[3]:
        x = 0
        y_step = 1
        while x < width - box[2]:
            x_step = 1
            if pixels[y*width + x] != emptyColor:
                retur.append((x, y, box[2] + x, box[3] + y))
                y_step = box[3] + 1
                x_step = box[2] + 1
            x += x_step
        y += y_step
    return retur

Adding another parameter to the call

for idx, box in enumerate(split(im, (0, 0, 365, 150))):
    im.crop(box).save("trim_{0}.png".format(idx))
N0b1ts
  • 192
  • 8
  • @ N0b1ts this i what i want.. but the thing is here, the size of trimmed image is 364*150 it should be 365*150 because this is the actual size of image. and my task is to compare all image with base image and it has to be equal. please help.. – Sachhya Mar 06 '18 at 13:29
  • 1
    Sorry, forgot an offset :) it has been corrected now. – N0b1ts Mar 06 '18 at 13:32
  • 1
    This solution will still fail if you have background pixels within the image in its first row. – N0b1ts Mar 06 '18 at 13:34
  • second solution handles all pixels but requires you to know the size of the images to extract. – N0b1ts Mar 06 '18 at 14:07
  • 1
    from your solution i can match trim images from base images.. size of the i mages varies image to image.. – Sachhya Mar 07 '18 at 05:03