Project

General

Profile

Revision 543:4190387a07c4

Added by Daniel Havlik almost 8 years ago

re #12065 refactor image diff composition code

View differences:

src/gocept/selenium/screenshot.py
14 14
    return pkg_resources.resource_filename('gocept.selenium', resource)
15 15

  
16 16

  
17
def image_diff_composition(exp, got):
18
    exp = exp.convert('RGB')
19
    got = got.convert('RGB')
20
    exp_txt = Image.open(get_path('exp_txt.png'))
21
    got_txt = Image.open(get_path('got_txt.png'))
22
    diff_txt = Image.open(get_path('diff_txt.png'))
23
    mask = Image.new('L', exp.size, 127)
24
    compo = Image.new('RGBA', (exp.size[0], exp.size[1]*3+60), (255,255,255,0))
25
    compo.paste(exp_txt, (5,0))
26
    compo.paste(exp, (0,20))
27
    got_pos = (0, exp.size[1]+40)
28
    got_txt_pos = (5, exp.size[1]+20)
29
    diff_pos = (0, exp.size[1]*2+60)
30
    diff_txt_pos = (5, exp.size[1]*2+40)
31
    compo.paste(got_txt, got_txt_pos)
32
    compo.paste(got, got_pos)
33
    compo.paste(diff_txt, diff_txt_pos)
34
    missing_red = ImageChops.invert(
35
        ImageChops.subtract(got, exp)).point(
36
            lambda i: 0 if i!=255 else 255).convert('1').convert(
37
                'RGB').split()[0]
38
    missing_red_mask = missing_red.point(lambda i: 80 if i!=255 else 255)
39
    missing_empty = Image.new('L', missing_red.size, 255)
40
    missing_r = Image.merge(
41
        'RGB', (missing_empty, missing_red, missing_red)).convert('RGBA')
42
    missing_green = ImageChops.invert(
43
        ImageChops.subtract(exp, got)).point(
44
            lambda i: 0 if i!=255 else 255).convert('1').convert(
45
                'RGB').split()[0]
46
    missing_green_mask = missing_green.point(lambda i: 80 if i!=255 else 255)
47
    missing_g = Image.merge(
48
        'RGB', (missing_green, missing_empty, missing_green)).convert('RGBA')
17
WHITE = (255, 255, 255, 0)
49 18

  
50
    exp.paste(got, exp.getbbox(), mask)
51
    exp.paste(missing_r, exp.getbbox(), ImageChops.invert(missing_red_mask))
52
    exp.paste(missing_g, exp.getbbox(), ImageChops.invert(missing_green_mask))
53
    compo.paste(exp, diff_pos)
54
    return compo
19

  
20
class DiffComposition(object):
21

  
22
    label_margin = 20
23

  
24
    def __init__(self, exp, got):
25
        self.exp = exp.convert('RGB')
26
        self.got = got.convert('RGB')
27
        self.width = self.exp.size[0]
28
        self.height = self.exp.size[1]
29
        self.prepare_composition()
30

  
31
    def prepare_composition(self):
32
        """prepares and returns the composition image, given width
33
        and height is the size of one of the three images"""
34
        #load the images with the labels
35
        exp_txt = Image.open(get_path('exp_txt.png'))
36
        got_txt = Image.open(get_path('got_txt.png'))
37
        diff_txt = Image.open(get_path('diff_txt.png'))
38
        #create emtpy image
39
        compo_size = (self.width, 3*(self.height+self.label_margin))
40
        self.compo = Image.new('RGBA', compo_size, WHITE)
41
        #paste the labels onto it
42
        for index, img in enumerate((exp_txt, got_txt, diff_txt)):
43
            pos = (5, index*(self.height+self.label_margin))
44
            self.compo.paste(img, pos)
45

  
46

  
47
    def paste_screenshots(self):
48
        for index, screenshot in enumerate((self.exp, self.got, self.diff)):
49
            pos = (0, (index*self.height)+((index+1)*self.label_margin))
50
            self.compo.paste(screenshot, pos)
51

  
52
    @property
53
    def composition(self):
54
        self.paste_screenshots()
55
        return self.compo
56

  
57
    @property
58
    def diff(self):
59
        def subtract(source, sub):
60
            return ImageChops.invert(
61
                ImageChops.subtract(source, sub)).point(
62
                    lambda i: 0 if i!=255 else 255).convert('1').convert(
63
                        'RGB').split()[0]
64
        def paste(dest, bbox, channels, merged):
65
            mask = channels.point(lambda i: 80 if i!=255 else 255)
66
            dest.paste(merged, bbox, ImageChops.invert(mask))
67
        missing_red = subtract(self.got, self.exp)
68
        missing_green = subtract(self.exp, self.got)
69
        missing_empty = Image.new('L', missing_red.size, 255)
70
        missing_red_merged = Image.merge(
71
            'RGB',
72
            (missing_empty, missing_red, missing_red)).convert('RGBA')
73
        missing_green_merged = Image.merge(
74
            'RGB',
75
            (missing_green, missing_empty, missing_green)).convert('RGBA')
76
        diff = self.exp.copy()
77
        exp_bbox = diff.getbbox()
78
        mask = Image.new('L', (self.width, self.height), 127)
79
        diff.paste(self.got, exp_bbox, mask)
80
        paste(diff, exp_bbox, missing_red, missing_red_merged)
81
        paste(diff, exp_bbox, missing_green, missing_green_merged)
82
        return diff
55 83

  
56 84

  
57 85
class ImageDiff(object):
......
176 204
            return
177 205
        ignored, compo_path = tempfile.mkstemp('.png')
178 206
        with open(compo_path, 'rw') as compo:
179
            compo_img = image_diff_composition(image, screenshot)
207
            compo_img = DiffComposition(image, screenshot).composition
180 208
            compo_img.save(compo.name)
181 209
            if SHOW_DIFF_IMG:
182 210
                compo_img.show()

Also available in: Unified diff