Beispiel #1
0
    def test_getdata(self):
        # test getheader/getdata against legacy values
        # Create a 'P' image with holes in the palette
        im = Image._wedge().resize((16, 16))
        im.putpalette(ImagePalette.ImagePalette('RGB'))
        im.info = {'background': 0}

        passed_palette = bytes(bytearray([255 - i // 3 for i in range(768)]))

        GifImagePlugin._FORCE_OPTIMIZE = True
        try:
            h = GifImagePlugin.getheader(im, passed_palette)
            d = GifImagePlugin.getdata(im)

            import pickle
            # Enable to get target values on pre-refactor version
            # with open('Tests/images/gif_header_data.pkl', 'wb') as f:
            #    pickle.dump((h, d), f, 1)
            with open('Tests/images/gif_header_data.pkl', 'rb') as f:
                (h_target, d_target) = pickle.load(f)

            self.assertEqual(h, h_target)
            self.assertEqual(d, d_target)
        finally:
            GifImagePlugin._FORCE_OPTIMIZE = False
Beispiel #2
0
    def test_getdata(self):
        # test getheader/getdata against legacy values
        # Create a 'P' image with holes in the palette
        im = Image._wedge().resize((16, 16))
        im.putpalette(ImagePalette.ImagePalette('RGB'))
        im.info = {'background': 0}

        passed_palette = bytes(bytearray([255-i//3 for i in range(768)]))

        GifImagePlugin._FORCE_OPTIMIZE = True
        try:
            h = GifImagePlugin.getheader(im, passed_palette)
            d = GifImagePlugin.getdata(im)

            import pickle
            # Enable to get target values on pre-refactor version
            # with open('Tests/images/gif_header_data.pkl', 'wb') as f:
            #    pickle.dump((h, d), f, 1)
            with open('Tests/images/gif_header_data.pkl', 'rb') as f:
                (h_target, d_target) = pickle.load(f)

            self.assertEqual(h, h_target)
            self.assertEqual(d, d_target)
        finally:
            GifImagePlugin._FORCE_OPTIMIZE = False
Beispiel #3
0
def test_getdata():
    # Test getheader/getdata against legacy values.
    # Create a 'P' image with holes in the palette.
    im = Image._wedge().resize((16, 16), Image.NEAREST)
    im.putpalette(ImagePalette.ImagePalette("RGB"))
    im.info = {"background": 0}

    passed_palette = bytes([255 - i // 3 for i in range(768)])

    GifImagePlugin._FORCE_OPTIMIZE = True
    try:
        h = GifImagePlugin.getheader(im, passed_palette)
        d = GifImagePlugin.getdata(im)

        import pickle

        # Enable to get target values on pre-refactor version
        # with open('Tests/images/gif_header_data.pkl', 'wb') as f:
        #    pickle.dump((h, d), f, 1)
        with open("Tests/images/gif_header_data.pkl", "rb") as f:
            (h_target, d_target) = pickle.load(f)

        assert h == h_target
        assert d == d_target
    finally:
        GifImagePlugin._FORCE_OPTIMIZE = False
Beispiel #4
0
    def test_save_netpbm_bmp_mode(self):
        with Image.open(TEST_GIF) as img:
            img = img.convert("RGB")

            tempfile = self.tempfile("temp.gif")
            GifImagePlugin._save_netpbm(img, 0, tempfile)
            with Image.open(tempfile) as reloaded:
                self.assert_image_similar(img, reloaded.convert("RGB"), 0)
Beispiel #5
0
def test_save_netpbm_l_mode(tmp_path):
    with Image.open(TEST_GIF) as img:
        img = img.convert("L")

        tempfile = str(tmp_path / "temp.gif")
        GifImagePlugin._save_netpbm(img, 0, tempfile)
        with Image.open(tempfile) as reloaded:
            assert_image_similar(img, reloaded.convert("L"), 0)
Beispiel #6
0
    def test_number_of_loops(self):
        number_of_loops = 2

        out = self.tempfile('temp.gif')
        with open(out, "wb") as fp:
            im = Image.new('L', (100, 100), '#000')
            for s in GifImagePlugin.getheader(im)[0] + GifImagePlugin.getdata(im, loop=number_of_loops):
                fp.write(s)
            fp.write(b";")
        reread = Image.open(out)

        self.assertEqual(reread.info['loop'], number_of_loops)
Beispiel #7
0
    def test_duration(self):
        duration = 1000

        out = self.tempfile('temp.gif')
        with open(out, "wb") as fp:
            im = Image.new('L', (100, 100), '#000')
            for s in GifImagePlugin.getheader(im)[0] + GifImagePlugin.getdata(im, duration=duration):
                fp.write(s)
            fp.write(b";")
        reread = Image.open(out)

        self.assertEqual(reread.info['duration'], duration)
Beispiel #8
0
    def test_number_of_loops(self):
        number_of_loops = 2

        out = self.tempfile("temp.gif")
        fp = open(out, "wb")
        im = Image.new("L", (100, 100), "#000")
        for s in GifImagePlugin.getheader(im)[0] + GifImagePlugin.getdata(im, loop=number_of_loops):
            fp.write(s)
        fp.write(b";")
        fp.close()
        reread = Image.open(out)

        self.assertEqual(reread.info["loop"], number_of_loops)
Beispiel #9
0
    def test_duration(self):
        duration = 1000

        out = self.tempfile("temp.gif")
        fp = open(out, "wb")
        im = Image.new("L", (100, 100), "#000")
        for s in GifImagePlugin.getheader(im)[0] + GifImagePlugin.getdata(im, duration=duration):
            fp.write(s)
        fp.write(b";")
        fp.close()
        reread = Image.open(out)

        self.assertEqual(reread.info["duration"], duration)
Beispiel #10
0
    def __init__(self, filename):
        self.source = Image.open(filename)
        self.palette = GifImagePlugin._get_palette_bytes(self.source)

        self.source.info[
            "disposal"] = 2  # This should get set automatically, but it doesn't so whatever, if your GIF looks f****d then its probably this
        self.source.encoderinfo = self.source.info
Beispiel #11
0
def get_tags(driver, path, filter=False):

    tags = set()
    frames = []
    video = path.suffix in ('.gif', '.webm', '.mp4')

    if video:

        tags.add('animated')

        if path.suffix in ('.webm', '.mp4'):
            try:
                for stream in FFProbe(str(path)).streams:
                    if stream.codec_type == 'audio':
                        tags.add('audio')
                        break
            except:
                pass

            vidcap = VideoCapture(str(path))
            frame_count = int(vidcap.get(CAP_PROP_FRAME_COUNT))
            vidcap.release()

        elif path.suffix in ('.gif'):

            gifcap = GifImagePlugin.GifImageFile(str(path))
            frame_count = gifcap.n_frames
            gifcap.close()

        step = 90 * log((frame_count * .002) + 1) + 1
        frames = video_generator(path, round(step))

    else:
        frames.append(path)

    for frame in frames:

        driver.get('http://dev.kanotype.net:8003/deepdanbooru/')
        driver.find('//*[@id="exampleFormControlFile1"]', str(frame))
        driver.find('//button[@type="submit"]', click=True)

        for _ in range(4):
            html = bs4.BeautifulSoup(driver.page_source(), 'lxml')
            try:
                tags.update([
                    tag.text for tag in html.find('tbody').findAll(href=True)
                ])
                break
            except AttributeError:
                if driver.current_url().endswith('deepdanbooru/'):
                    driver.find('//*[@id="exampleFormControlFile1"]',
                                str(frame))
                    driver.find('//button[@type="submit"]', click=True)
                driver.refresh()

    if filter: tags.difference_update(REMOVE)

    return ' '.join(tags)
Beispiel #12
0
 def __iadd__(self, other):
     if self.previous is None:
         # Globaler Header
         header = ''.join(GifImagePlugin.getheader(other))
         header = header.replace('GIF87a', 'GIF89a')
         self.fo.write(header)
         # Graphic Control Extension-Block
         header = [
                 '\x21',     # Signatur für Beginn eines
                             # Extension-Blocks
                 '\xf9',     # Graphic Control Extension-Signatur
                 '\x04\x00', # Größe des Blocks (4 Bytes)
                 '\x0a\x00', # Irgendwas + reservierter Block
                 '\xff\x00', # Pause zwischen Frames (1/100 s)
             ]
         self.fo.write(''.join(header))
         # Application Extension Block
         header = [
                 '\x21',     # Signatur für Beginn eines
                             # Extension-Blocks
                 '\xff',     # Application Extension-Signatur
                 '\x0b',     # Größe des Blocks (11 Bytes)
                 'NETSCAPE2.0',
                 '\x03',     # Größe des Sub-Datenblocks (3 Bytes)
                 '\x01',
                 '\x00\x00', # Anzahl der Schleifen (0 = unendlich)
                 '\x00'      # Ende des Blocks
             ]
         #self.fo.write(''.join(header))
         # Erstes Frame
         for string in GifImagePlugin.getdata(other):
             self.fo.write(string)
     else:
         # Delta-Frame
         delta = ImageChops.subtract_modulo(other, self.previous)
         bbox = delta.getbbox()
         if bbox:
             for string in GifImagePlugin.getdata(other.crop(bbox),
                                                  offset=bbox[:2]):
                 self.fo.write(string)
         else:
             # XXX Was macht man in dem Fall?
             pass
     self.previous = other.copy()
     return self
Beispiel #13
0
 def __iadd__(self, other):
     if self.previous is None:
         # Globaler Header
         header = "".join(GifImagePlugin.getheader(other))
         header = header.replace("GIF87a", "GIF89a")
         self.fo.write(header)
         # Graphic Control Extension-Block
         header = [
             "\x21",  # Signatur für Beginn eines
             # Extension-Blocks
             "\xf9",  # Graphic Control Extension-Signatur
             "\x04\x00",  # Größe des Blocks (4 Bytes)
             "\x0a\x00",  # Irgendwas + reservierter Block
             "\xff\x00",  # Pause zwischen Frames (1/100 s)
         ]
         self.fo.write("".join(header))
         # Application Extension Block
         header = [
             "\x21",  # Signatur für Beginn eines
             # Extension-Blocks
             "\xff",  # Application Extension-Signatur
             "\x0b",  # Größe des Blocks (11 Bytes)
             "NETSCAPE2.0",
             "\x03",  # Größe des Sub-Datenblocks (3 Bytes)
             "\x01",
             "\x00\x00",  # Anzahl der Schleifen (0 = unendlich)
             "\x00",  # Ende des Blocks
         ]
         # self.fo.write(''.join(header))
         # Erstes Frame
         for string in GifImagePlugin.getdata(other):
             self.fo.write(string)
     else:
         # Delta-Frame
         delta = ImageChops.subtract_modulo(other, self.previous)
         bbox = delta.getbbox()
         if bbox:
             for string in GifImagePlugin.getdata(other.crop(bbox), offset=bbox[:2]):
                 self.fo.write(string)
         else:
             # XXX Was macht man in dem Fall?
             pass
     self.previous = other.copy()
     return self
Beispiel #14
0
def build_animated_gif(stream, images, delay=0.1):
    """Writes an animated GIF into a stream given an iterator of PIL.Images.

    See http://en.wikipedia.org/wiki/Graphics_Interchange_Format#Animated_GIF.
    """
    # Process the images lazily to avoid unnecessary memory load. The first
    # image is used to build the GIF headers.
    images = (image.convert('P') for image in images)
    image = images.next()

    # Header
    stream.write("GIF89a")

    # Logical Screen Descriptor
    stream.write(struct.pack('<H', image.size[0]))
    stream.write(struct.pack('<H', image.size[1]))
    stream.write("\x87\x00\x00")

    # Palette
    stream.write(GifImagePlugin.getheader(image)[1])

    # Application Extension
    stream.write("\x21\xFF\x0B")
    stream.write("NETSCAPE2.0")
    stream.write("\x03\x01")
    stream.write(struct.pack('<H', 2**16 - 1))
    stream.write('\x00')

    for im in itertools.chain([image], images):
        # Graphic Control Extension
        stream.write('\x21\xF9\x04')
        stream.write('\x08')
        stream.write(struct.pack('<H', int(round(delay * 100))))
        stream.write('\x00\x00')

        data = GifImagePlugin.getdata(im)
        for d in data:
            stream.write(d)

    # GIF file terminator
    stream.write(";")
def build_animated_gif(stream, images, delay=0.1):
    """Writes an animated GIF into a stream given an iterator of PIL.Images.

    See http://en.wikipedia.org/wiki/Graphics_Interchange_Format#Animated_GIF.
    """
    # Process the images lazily to avoid unnecessary memory load. The first
    # image is used to build the GIF headers.
    images = (image.convert('P') for image in images)
    image = images.next()

    # Header
    stream.write("GIF89a")

    # Logical Screen Descriptor
    stream.write(struct.pack('<H', image.size[0]))
    stream.write(struct.pack('<H', image.size[1]))
    stream.write("\x87\x00\x00")

    # Palette
    stream.write(GifImagePlugin.getheader(image)[1])

    # Application Extension
    stream.write("\x21\xFF\x0B")
    stream.write("NETSCAPE2.0")
    stream.write("\x03\x01")
    stream.write(struct.pack('<H', 2**16-1))
    stream.write('\x00')

    for im in itertools.chain([image], images):
        # Graphic Control Extension
        stream.write('\x21\xF9\x04')
        stream.write('\x08')
        stream.write(struct.pack('<H', int(round(delay*100))))
        stream.write('\x00\x00')

        data = GifImagePlugin.getdata(im)
        for d in data:
            stream.write(d)

    # GIF file terminator
    stream.write(";")
Beispiel #16
0
def writeImage(out, frames, filename="blurple.gif"):
    # Instead of saving a series of complete images, this saves the deltas
    for s in GifImagePlugin._get_global_header(frames[0], frames[0].info):
        out.write(s)
    for frame in frames:
        dispose_extent = frame.dispose_extent
        disposal_method = frame.disposal_method
        include_color_table = frame.palette.palette != frame.global_palette.palette
        frame = frame.crop(dispose_extent)
        GifImagePlugin._write_frame_data(
            out,
            frame,
            dispose_extent[:2],
            {
                'disposal': disposal_method,
                'duration': frame.info["duration"],
                'include_color_table': include_color_table,
                'transparency': 255,
                'loop': frame.info["loop"],
            },
        )
Beispiel #17
0
    def write_gif(self, fp, im_frames):
        frame_count = 0
        if len(im_frames) > 1:
            for frame_data in im_frames:
                im_frame = frame_data['im']

                if frame_count == 0:
                    # global header
                    for s in GifImagePlugin._get_global_header(
                            im_frame, frame_data['encoderinfo']):
                        fp.write(s)
                else:
                    frame_data['encoderinfo']['include_color_table'] = True

                offset = (0, 0)
                GifImagePlugin._write_frame_data(fp, im_frame, offset,
                                                 frame_data['encoderinfo'])

                frame_count += 1

            fp.write(b";")

        print(f'Wrote {frame_count} frames')
Beispiel #18
0
 def _open(self):
     # Screen
     s = self.fp.read(13)
     if s[:6] not in ["GIF87a", "GIF89a"]:
         raise SyntaxError, "not a GIF file"
     self.info["version"] = s[:6]
     self.size = GifImagePlugin.i16(s[6:]), GifImagePlugin.i16(s[8:])
     self.tile = []
     flags = ord(s[10])
     bits = (flags & 7) + 1
     if flags & 128:
         # get global palette
         self.info["background"] = ord(s[11])
         # check if palette contains colour indices
         p = self.fp.read(3 << bits)
         for i in range(0, len(p), 3):
             if not (chr(i / 3) == p[i] == p[i + 1] == p[i + 2]):
                 p = ImagePalette.raw("RGB", p)
                 self.global_palette = self.palette = p
                 break
     self.__fp = self.fp
     self.__rewind = self.fp.tell()
     self.seek(0)  # get ready to read first frame
 def _open(self):
     # Screen
     s = self.fp.read(13)
     if s[:6] not in ["GIF87a", "GIF89a"]:
         raise SyntaxError, "not a GIF file"
     self.info["version"] = s[:6]
     self.size = GifImagePlugin.i16(s[6:]), GifImagePlugin.i16(s[8:])
     self.tile = []
     flags = ord(s[10])
     bits = (flags & 7) + 1
     if flags & 128:
         # get global palette
         self.info["background"] = ord(s[11])
         # check if palette contains colour indices
         p = self.fp.read(3<<bits)
         for i in range(0, len(p), 3):
             if not (chr(i/3) == p[i] == p[i+1] == p[i+2]):
                 p = ImagePalette.raw("RGB", p)
                 self.global_palette = self.palette = p
                 break
     self.__fp = self.fp
     self.__rewind = self.fp.tell()
     self.seek(0) # get ready to read first frame
Beispiel #20
0
def make_animated_gif(stream, images, delays):
    '''
    Adapted from https://github.com/GoogleCloudPlatform/appengine-mandelbrot-python/blob/master/mandelbrot_animation.py
    '''
    image = images[0]

    # Header
    stream.write("GIF89a")

    # Logical Screen Descriptor
    stream.write(struct.pack('<H', image.size[0]))
    stream.write(struct.pack('<H', image.size[1]))
    stream.write("\x87\x00\x00")

    # Palette
    stream.write(GifImagePlugin.getheader(image)[1])

    # Application Extension
    stream.write("\x21\xFF\x0B")
    stream.write("NETSCAPE2.0")
    stream.write("\x03\x01")
    stream.write(struct.pack('<H', 2 ** 16 - 1))
    stream.write('\x00')

    for i in xrange(1, len(images)):
        # Graphic Control Extension
        stream.write('\x21\xF9\x04')
        stream.write('\x08')
        stream.write(struct.pack('<H', delays[i]))
        stream.write('\x00\x00')

        data = GifImagePlugin.getdata(images[i])
        for d in data:
            stream.write(d)

    # GIF file terminator
    stream.write(";")
Beispiel #21
0
    def prepare_glitch(self, offset=100):
        # MODIFIED FROM
        # https://github.com/python-pillow/Pillow/blob/48a05e6cf3fc98b6385034372143f06fe6719e4e/src/PIL/GifImagePlugin.py#L416

        duration = self.source.encoderinfo.get(
            "duration", self.source.info.get("duration"))
        disposal = self.source.encoderinfo.get(
            "disposal", self.source.info.get("disposal"))

        im_frames = []
        frame_count = 0
        for imSequence in itertools.chain([self.source],
                                          self.source.encoderinfo.get(
                                              "append_images", [])):
            for im_frame in ImageSequence.Iterator(imSequence):
                # a copy is required here since seek can still mutate the image
                im_frame = GifImagePlugin._normalize_mode(im_frame.copy())
                if frame_count == 0:
                    for k, v in im_frame.info.items():
                        self.source.encoderinfo.setdefault(k, v)
                im_frame = GifImagePlugin._normalize_palette(
                    im_frame, self.palette, self.source.encoderinfo)

                encoderinfo = self.source.encoderinfo.copy()
                if isinstance(duration, (list, tuple)):
                    encoderinfo['duration'] = duration[frame_count]
                if isinstance(disposal, (list, tuple)):
                    encoderinfo["disposal"] = disposal[frame_count]
                frame_count += 1

                # Crop the image to add <glitch_offset> px to the bottom
                im_frame = im_frame.crop(
                    (0, 0, self.source.size[0], self.source.size[1] + offset))

                im_frames.append({'im': im_frame, 'encoderinfo': encoderinfo})

            return im_frames
def write_image(out, frames, filename="blurple.gif"):
    """Instead of saving a series of complete images, this saves the deltas.
    Useful for making GIFs not take as much space.
    Raw function: don't use this unless you know what you're doing.
    """
    for s in GifImagePlugin._get_global_header(frames[0], frames[0].info):
        out.write(s)
    for frame in frames:
        dispose_extent = frame.dispose_extent
        disposal_method = frame.disposal_method
        include_color_table = frame.palette.palette != frame.global_palette.palette
        frame = frame.crop(dispose_extent)
        GifImagePlugin._write_frame_data(
            out,
            frame,
            dispose_extent[:2],
            {
                "disposal": disposal_method,
                "duration": frame.info["duration"],
                "include_color_table": include_color_table,
                "transparency": 255,
                "loop": frame.info["loop"],
            },
        )
Beispiel #23
0
def level_22():
    f=GifImagePlugin.GifImageFile(r'white.gif')
    my=Image.new('RGB',(640,480)) # 用于画字符的图片
    draw=ImageDraw.Draw(my)
    curpoint=[0,0]
    pointlist=[tuple(curpoint)]
    frameno=1
    while True:
        print ('frame=%d'%(frameno,))
        try:
            for y in range(98,103):#f.size[1]):
                for x in range(98,103):#f.size[0]):
                    if f.getpixel((x,y))!=0:
                        print ('%d: %d,%d=%d'%(frameno,x,y,f.getpixel((x,y))))
        # 可知每帧里面都有个调色板索引为8的点,坐标范围在(98,98)-(102,102)之间且坐标为偶数,相当于在3×3的九宫格中
                        k='%d-%d'%(x,y)
        # 到此为止没有思路了。参考攻略,原来是网页上那个游戏摇杆的图片是暗示你九宫格的点是用矢量方法记录的,可以据此划出线条来,太有想象力了!
        #(98,98) (100,98) (102,98)   (-1,-1) (0,-1) (1,-1)
        #(98,100)(100,100)(102,100) == (-1,0) (0,0) (1,0)
        #(98,102)(100,102)(102,102)   (-1,1) (0,1) (1,1)
                        d={ '98-98':(-5,-5),'100-98':(0,-5),'102-98':(5,-5),
                                '98-100':(-5,0),'100-100':(0,0),'102-100':(5,0),
                          '98-102':(-5,5),'100-102':(0,5),'102-102':(5,5)}
                        if d[k]==(0,0):
                            print ('回到原点,开始画新字符')
                            if len(pointlist)>1:
                                draw.line(pointlist) # 画出字符
                                del pointlist[:] # 清空列表
                                curpoint[0]+=50 # 设定开始画字符的坐标,以免把上一个字符覆盖
                                curpoint[1]+=50
                                pointlist.append(tuple(curpoint))
                            continue
                        curpoint[0]+=d[k][0]
                        curpoint[1]+=d[k][1]
                        pointlist.append(tuple(curpoint))

            f.seek(f.tell()+1) # 跳到下一帧
            frameno+=1

        except EOFError as e: # 最后一帧后会触发此异常
            print ('end of frame.%d'%(frameno,))
            # 可知此GIF有133帧
            draw.line(pointlist) # 画出最后一个字符
            my.save(r'23_white.png','png') 
            # 能看出画的字符为 bonus ==> http://www.pythonchallenge.com/pc/hex/bonus.html
            break
Beispiel #24
0
def level_16():
##      # 尝试把不是粉短线的颜色都去掉
##      f=GifImagePlugin.GifImageFile(ur'd:\mozart.gif')
##      mf=PIL.Image.new('P',f.size)
##      for y in range(f.size[1]):
##              for x in range(f.size[0]):
##                      if f.getpixel((x,y))==195:
##                              mf.putpixel((x,y),195)
##      mf.save(ur'd:\16.gif','gif') # 啥都看不出来 查看攻略 原来所谓get this straight是说把这些粉短线都按行对齐

        f=GifImagePlugin.GifImageFile(r'mozart.gif')
        mf=Image.new('P',f.size)
        mf.putpalette(f.getpalette()) 
        # 用原图的调色板
        for y in range(f.size[1]):
                for x in range(f.size[0]):
                        if f.getpixel((x,y))==195: 
                            # 找到头一个粉色像素 以此为对准线
                                for mx in range(f.size[0]):
                                        mf.putpixel((mx,y),f.getpixel(((mx+x)%f.size[0],y))) 
                                        #往前走mx<--mx+x之前替换
                                        # 将从这个粉色像素开始的一行复制到新图片中
                                break
        mf.save(r'mozart16.gif','gif') 
Beispiel #25
0
def gif_image():
    return GifImagePlugin.GifImageFile(create_test_image('gif'))
Beispiel #26
0
    def test_save_netpbm_l_mode(self):
        img = Image.open(TEST_GIF).convert("L")

        tempfile = self.tempfile("temp.gif")
        GifImagePlugin._save_netpbm(img, 0, tempfile)
        self.assert_image_similar(img, Image.open(tempfile).convert("L"), 0)
Beispiel #27
0
def export_animation(app, art, out_filename, bg_color=None, loop=True):
    # get list of rendered frame images
    frames = []
    # use arbitrary color for transparency
    i_transp = art.palette.get_random_non_palette_color()
    # if bg color is specified, this isn't art mode; play along
    if bg_color is not None:
        f_transp = bg_color
        art.palette.colors[0] = (round(bg_color[0] * 255),
                                 round(bg_color[1] * 255),
                                 round(bg_color[2] * 255), 255)
    else:
        # GL wants floats
        f_transp = (i_transp[0] / 255, i_transp[1] / 255, i_transp[2] / 255,
                    1.)
    for frame in range(art.frames):
        frame_img = get_frame_image(app,
                                    art,
                                    frame,
                                    allow_crt=False,
                                    scale=1,
                                    bg_color=f_transp)
        if bg_color is not None:
            # if bg color is specified, assume no transparency
            frame_img = art.palette.get_palettized_image(
                frame_img, force_no_transparency=True)
        else:
            frame_img = art.palette.get_palettized_image(
                frame_img, i_transp[:3])
        frames.append(frame_img)
    # compile frames into animated GIF with proper frame delays
    # technique thanks to:
    # https://github.com/python-pillow/Pillow/blob/master/Scripts/gifmaker.py
    output_img = open(out_filename, 'wb')
    for i, img in enumerate(frames):
        delay = art.frame_delays[i] * 1000
        if i == 0:
            data = GifImagePlugin.getheader(img)[0]
            # PIL only wants to write GIF87a for some reason...
            # welcome to 1989 B]
            data[0] = data[0].replace(b'7', b'9')
            # TODO: loop doesn't work?
            if bg_color is not None:
                # if bg color is specified, assume no transparency
                if loop:
                    data += GifImagePlugin.getdata(img, duration=delay, loop=0)
                else:
                    data += GifImagePlugin.getdata(img, duration=delay)
            else:
                data += GifImagePlugin.getdata(img,
                                               duration=delay,
                                               transparency=0,
                                               loop=0)
            for b in data:
                output_img.write(b)
            continue
        delta = ImageChops.subtract_modulo(img, frames[i - 1])
        # Image.getbbox() rather unhelpfully returns None if no delta
        dw, dh = delta.size
        bbox = delta.getbbox() or (0, 0, dw, dh)
        for b in GifImagePlugin.getdata(img.crop(bbox),
                                        offset=bbox[:2],
                                        duration=delay,
                                        transparency=0,
                                        loop=0):
            output_img.write(b)
    output_img.write(b';')
    output_img.close()
    output_format = 'Animated GIF'
    def seek(self, frame):
        if frame == 0:
            # rewind
            self.__offset = 0
            self.dispose = None
            self.__frame = -1
            self.__fp.seek(self.__rewind)
        if frame != self.__frame + 1:
            raise ValueError, "cannot seek to frame %d" % frame
        self.__frame = frame
        self.tile = []
        self.fp = self.__fp
        if self.__offset:
            # backup to last frame
            self.fp.seek(self.__offset)
            while self.data():
                pass
            self.__offset = 0
        if self.dispose:
            self.im = self.dispose
            self.dispose = None
        self.palette = self.global_palette
        while 1:
            s = self.fp.read(1)
            if not s or s == ";":
                break
            elif s == "!":
                #
                # extensions
                #
                s = self.fp.read(1)
                block = self.data()
                if ord(s) == 249:
                    #
                    # graphic control extension
                    #
                    flags = ord(block[0])
                    if flags & 1:
                        self.info["transparency"] = ord(block[3])
                    self.info["duration"] = GifImagePlugin.i16(block[1:3]) * 10
                    try:
                        # disposal methods
                        if flags & 8:
                            # replace with background colour
                            self.dispose = Image.core.fill("P", self.size,
                                self.info["background"])
                        elif flags & 16:
                            # replace with previous contents
                            self.dispose = self.im.copy()
                    except (AttributeError, KeyError):
                        pass
                elif ord(s) == 255:
                    #
                    # application extension
                    #
                    self.info["extension"] = block, self.fp.tell()
                    if block[:11] == "NETSCAPE2.0":
                        block = self.data()
                        if len(block) >= 3 and ord(block[0]) == 1:
                            self.info["loop"] = GifImagePlugin.i16(block[1:3])
                while self.data():
                    pass
            elif s == ",":
                #
                # local image
                #
                s = self.fp.read(9)
                # extent
                x0, y0 = GifImagePlugin.i16(s[0:]), GifImagePlugin.i16(s[2:])
                x, y = GifImagePlugin.i16(s[4:]), GifImagePlugin.i16(s[6:])
                x1, y1 = x0 + x, y0 + y
                self.info['frame_box'] = (x0,y0,x1,y1)
                flags = ord(s[8])
                interlace = (flags & 64) != 0
                if flags & 128:
                    bits = (flags & 7) + 1
                    self.palette =\
                        ImagePalette.raw("RGB", self.fp.read(3<<bits))

                # image data
                bits = ord(self.fp.read(1))
                self.__offset = self.fp.tell()
                self.tile = [("gif",
                             (x0, y0, x1, y1),
                             self.__offset,
                             (bits, interlace))]
                break
            else:
                pass
                # raise IOError, "illegal GIF tag `%x`" % ord(s)
        if not self.tile:
            # self.__fp = None
            raise EOFError, "no more images in GIF file"
        self.mode = "L"
        if self.palette:
            self.mode = "P"
Beispiel #29
0
    def seek(self, frame):
        if frame == 0:
            # rewind
            self.__offset = 0
            self.dispose = None
            self.__frame = -1
            self.__fp.seek(self.__rewind)
        if frame != self.__frame + 1:
            raise ValueError, "cannot seek to frame %d" % frame
        self.__frame = frame
        self.tile = []
        self.fp = self.__fp
        if self.__offset:
            # backup to last frame
            self.fp.seek(self.__offset)
            while self.data():
                pass
            self.__offset = 0
        if self.dispose:
            self.im = self.dispose
            self.dispose = None
        self.palette = self.global_palette
        while 1:
            s = self.fp.read(1)
            if not s or s == ";":
                break
            elif s == "!":
                #
                # extensions
                #
                s = self.fp.read(1)
                block = self.data()
                if ord(s) == 249:
                    #
                    # graphic control extension
                    #
                    flags = ord(block[0])
                    if flags & 1:
                        self.info["transparency"] = ord(block[3])
                    self.info["duration"] = GifImagePlugin.i16(block[1:3]) * 10
                    try:
                        # disposal methods
                        if flags & 8:
                            # replace with background colour
                            self.dispose = Image.core.fill(
                                "P", self.size, self.info["background"])
                        elif flags & 16:
                            # replace with previous contents
                            self.dispose = self.im.copy()
                    except (AttributeError, KeyError):
                        pass
                elif ord(s) == 255:
                    #
                    # application extension
                    #
                    self.info["extension"] = block, self.fp.tell()
                    if block[:11] == "NETSCAPE2.0":
                        block = self.data()
                        if len(block) >= 3 and ord(block[0]) == 1:
                            self.info["loop"] = GifImagePlugin.i16(block[1:3])
                while self.data():
                    pass
            elif s == ",":
                #
                # local image
                #
                s = self.fp.read(9)
                # extent
                x0, y0 = GifImagePlugin.i16(s[0:]), GifImagePlugin.i16(s[2:])
                x, y = GifImagePlugin.i16(s[4:]), GifImagePlugin.i16(s[6:])
                x1, y1 = x0 + x, y0 + y
                self.info['frame_box'] = (x0, y0, x1, y1)
                flags = ord(s[8])
                interlace = (flags & 64) != 0
                if flags & 128:
                    bits = (flags & 7) + 1
                    self.palette =\
                        ImagePalette.raw("RGB", self.fp.read(3<<bits))

                # image data
                bits = ord(self.fp.read(1))
                self.__offset = self.fp.tell()
                self.tile = [("gif", (x0, y0, x1, y1), self.__offset,
                              (bits, interlace))]
                break
            else:
                pass
                # raise IOError, "illegal GIF tag `%x`" % ord(s)
        if not self.tile:
            # self.__fp = None
            raise EOFError, "no more images in GIF file"
        self.mode = "L"
        if self.palette:
            self.mode = "P"
Beispiel #30
0
    def test_save_netpbm_l_mode(self):
        img = Image.open(TEST_GIF).convert("L")

        tempfile = self.tempfile("temp.gif")
        GifImagePlugin._save_netpbm(img, 0, tempfile)
        self.assert_image_similar(img, Image.open(tempfile).convert("L"), 0)
Beispiel #31
0
    def test_invalid_file(self):
        invalid_file = "Tests/images/flower.jpg"

        self.assertRaises(SyntaxError,
                          lambda: GifImagePlugin.GifImageFile(invalid_file))
Beispiel #32
0
def level_27():
    zig=GifImagePlugin.GifImageFile(r'zigzag.gif')
    zigdata=zig.tostring()
    import array
    data=[]
    for i in zigdata[:10]:
        data.append(i)
    data = array.array("B", data).tostring()
    print("zigdata,10:",data[:10])
    
    print (''.join(['%X'%(i,) for i in zigdata[:20]]))
    # 查看前面几个字节,没有头绪)

    #print (len(zig.getcolors()))
    palette=zig.palette.getdata()[1][::3] # 获取其调色板
    data1=[]
    for i in palette[:10]:
        data1.append(i)
    data1 = array.array("B", data1).tostring()
    print("palette,10:",palette[:10])
    #print(data1,type(data1))

    print (''.join(['%X'%(i,) for i in palette[:20]]))

    #t=string.maketrans(''.join([chr(i) for i in range(256)]),palette)
    ch1=b''.join([bytes([i]) for i in range(256)])
    t=bytes.maketrans(ch1,palette)
    zigtrans=zigdata.translate(t) # 用调色板值转换像素值
    print("zigtrans,10",zigtrans[:10])
    print (''.join(['%X'%(i,) for i in zigtrans[:20]]))
    #实现hex(zigtrans[:20],python3下,前面为python2版
    # 还是看不出来什么,不过似乎转换后的数据除了第一个字节外都与原数据很相似)

    print (zigdata[1:]==zigtrans[:-1])
    # 尝试将两组数据中所有不相同的字节放在一起
    deltas=filter(lambda p:p[0]!=p[1],zip(zigdata[1:],zigtrans[:-1]))
    diffs=[b''.join([bytes([p[i]]) for p in deltas]) for i in range(2)]
    print (diffs[0][:20])
    # 看起来是个bz文件)
    print (diffs[1][:20])
    #这一句结果与别人的不同也.

    bz=bz2.BZ2Decompressor().decompress(diffs[0])
    #bz=bz2.decompress(diffs[0])#在python3下要用上面这一句,真是奇怪
    #也许比较的是字节吧
    print (len(bz))
    print (bz[:100])
    # 输出是python的关键字和地址 ../ring/bell.html

    keywords=bz.split(b' ')
    keys={}
    for k in keywords: keys[k]=1
    print (keys.keys())

    print (len(keywords))
    print (len(keys.keys()))
    # 很多关键字
    print (len(keywords)/len(keys.keys()))

    # 将不一样的像素按位置显示出来
    im=Image.new('1',zig.size,0)
    im.putdata([ p[0]==p[1] for p in zip(zigdata[1:],zigtrans[:-1])])
    #im.show() 

    # 有个钥匙图样,左边是not,右边是word,下面是busy?
    # 暗示 not key word
    # 那么找找上面看到的那些关键字里面哪些不是key word
    im.save("27_notkeyword.png","png")

    for k in keys.keys():
        k=str(k)[2:-1]
        if not keyword.iskeyword(k):
            print (k)
            # 打印出来 switch 和 repeat 不是关键字,../ring/bell.html不算。

    # 用switch 和 repeat 分别做用户名和密码,还有print,exec,当然这是python3下的
    k1,k2='switch','repeat'
    t=((k1+":"+k2),(k2+":"+k1))
    n1 = urllib.request.FancyURLopener()
    for i in t:
        try:
            url='http://'+i+'@www.pythonchallenge.com/pc/ring/bell.html'
            r=n1.open(url)
            if r:
                print ('got, %s '%(i))
                # 正确的用户名是repeat 密码是 switch ==> http://www.pythonchallenge.com/pc/ring/bell.html
                break
        except urllib.request.HTTPError:
            pass
Beispiel #33
0
def test_invalid_file():
    invalid_file = "Tests/images/flower.jpg"

    with pytest.raises(SyntaxError):
        GifImagePlugin.GifImageFile(invalid_file)