def _loadGIFSequence(imagePath, layout, bgcolor, bright, offset):
    img = Image.open(imagePath)
    if offset == (0, 0):
        w = 0
        h = 0
        if img.size[0] < layout.width:
            w = (layout.width - img.size[0]) // 2
        if img.size[1] < layout.height:
            h = (layout.height - img.size[1]) // 2
        offset = (w, h)

    images = []
    count = 0
    for frame in ImageSequence.Iterator(img):
        images.append(_getBufferFromImage(frame, layout, bgcolor, bright, offset))
        count += 1

    return images
Beispiel #2
0
def freme_func(img):
    try:
        img = Image.open(img)
    except IOError:
        print("Fail to open image")

    dic_list = []
    index = 0
    for frame in ImageSequence.Iterator(img):
        filename = str(index) + ".png"
        frame.save(os.path.join(config.BASE_DIR, 'picture/') + filename)
        dic = {"name": filename, "url": "http://172.16.60.192:8080" + os.path.join(config.BASE_DIR, 'picture/') + filename}
        dic_list.append(dic)
        index += 1

    # print(dic_list)
    with open('freme.json', 'w') as f:
        f.write(json.dumps(dic_list))
Beispiel #3
0
def read_image2RGBbytes(image_path):
    jpgext = ['.jpg', '.jpeg', '.JPG', '.JPEG']
    print(image_path)
    # if (os.path.splitext(image_path)[1] in jpgext):
    #   image_data = gfile.FastGFile(image_path, 'rb').read()
    # else:
    with BytesIO() as output:
        with Image.open(image_path) as img:
            frames = [frame.copy() for frame in ImageSequence.Iterator(img)]
            frameCount = len(frames)
            if frameCount < 5:
                temImg = frames[frameCount // 2]
                temImg.convert('RGB').save(output, 'JPEG')
            else:
                temImg = frames[frameCount - 4]
                temImg.convert('RGB').save(output, 'JPEG')
            image_data = output.getvalue()
    return image_data
    def test_sanity(self):

        test_file = self.tempfile("temp.im")

        im = hopper("RGB")
        im.save(test_file)

        seq = ImageSequence.Iterator(im)

        index = 0
        for frame in seq:
            self.assert_image_equal(im, frame)
            self.assertEqual(im.tell(), index)
            index += 1

        self.assertEqual(index, 1)

        self.assertRaises(AttributeError, ImageSequence.Iterator, 0)
Beispiel #5
0
def main(imgPath, offsetX=0, offsetY=0, algo=0):
    img = Image.open(imgPath)
    duration = img.info.get('duration', -1)
    if not hasattr(img, 'n_frames'):
        img.n_frames = 1
    print("converting image... 0/" + str(img.n_frames) + " done", end='\r')
    imageBuffer = []
    i = 0
    ii = ImageSequence.Iterator(img)
    for frame in ii:
        #frame.save('rendered/test_%02d.png' % i, 'PNG')
        imageBuffer.append(generatePFLines(frame, offsetX, offsetY, algo))
        i += 1
        print("converting image... " + str(i) + "/" + str(img.n_frames) +
              " done",
              end='\r')
    print()
    return {'frameBuffer': imageBuffer, 'duration': duration}
    def matrix_setup(self):
        self.images = []
        self.p_type = self.led_config.matrix_pattern_type
        self.last_type = ""
        self.led = LEDMatrix(self.driver,
                             width=self.led_config.matrix_width,
                             height=self.led_config.matrix_height,
                             serpentine=self.serpentine,
                             vert_flip=self.vert_flip,
                             rotation=self.rotation,
                             threadedUpdate=self.led_config.multiprocess)

        image_path = self.led_config.image_path
        for frame in ImageSequence.Iterator(Image.open(image_path)):
            rgba = Image.new("RGBA", frame.size)
            rgba.paste(frame)
            self.images.append(rgba)
        self.base_image = Image.new("RGBA", self.images[0].size)

        self.drops = [[0 for _ in range(self.led_config.matrix_height)]
                      for _ in range(self.led_config.matrix_width)]

        self._len = (self.led_config.matrix_width *
                     2) + (self.led_config.matrix_height * 2) - 2
        self._step = 1
        self._bstep = 0
        midx = int(self.led_config.matrix_height / 2)
        if float(midx) == (self.led_config.matrix_height / 2):
            # even number, two center px
            self.midxa = midx
            self.midxb = midx - 1
        else:
            # odd number, one center px
            self.midxa = midx
            self.midxb = midx
        midy = int(self.led_config.matrix_width / 2)
        if float(midy) == (self.led_config.matrix_width / 2):
            # even number, two center px
            self.midya = midy
            self.midyb = midy - 1
        else:
            # odd number, one center px
            self.midya = midy
            self.midyb = midy
Beispiel #7
0
    def paste_image_behind(self,
                           input_path: str,
                           output_path: str,
                           paste_img_path: str,
                           *,
                           mirror: bool = False):
        front = Image.open(paste_img_path).convert('RGBA')
        try:
            image = Image.open(input_path).convert('RGBA')
        except:
            image = Image.open(input_path).convert('RGB')
        final_width, final_height = front.size

        if mirror:
            front = ImageOps.mirror(front)

        if input_path.endswith('gif') or input_path.endswith('gifv'):
            image = Image.open(input_path)
            image = image.resize((final_width, final_height))
            dur = 1000 / image.info['duration']
            frames = []
            for frame in ImageSequence.Iterator(image):
                frame.thumbnail((final_width, final_height), Image.ANTIALIAS)

                transparent = Image.new('RGBA', (final_width, final_height),
                                        (0, 0, 0, 0))
                transparent.paste(frame, (0, 0))
                transparent.paste(front, (0, 0), mask=front)
                frames.append(transparent)

            frames[0].save(output_path,
                           format='GIF',
                           append_images=frames[1:],
                           save_all=True,
                           loop=0,
                           duration=round(dur * 0.90))
        else:
            image = image.resize((final_width, final_height))
            transparent = Image.new('RGBA', (final_width, final_height),
                                    (0, 0, 0, 0))
            transparent.paste(image, (0, 0))
            transparent.paste(front, (0, 0), mask=front)
            transparent.save(output_path, format='PNG')
        return output_path
Beispiel #8
0
def change_and_upload(filename):
    basename = os.path.basename(filename)
    filename = 'original/' + basename
    new_filename = 'gif/' + basename
    im = Image.open(filename)
    # GIF图片流的迭代器
    iter = ImageSequence.Iterator(im)

    # 列出目录
    for file in os.listdir('./out'):
        os.remove('./out/' + file)

    time.sleep(1)

    imgs = []
    index = 1
    # 遍历图片流的每一帧
    for frame in iter:

        img = frame.convert('RGB')
        frame.save("./out/%d.png" % index)
        # arr = np.array(frame)
        index += 1

    a = os.listdir('./out')
    # a.sort(key=lambda x : int(x[:-4]))
    a.sort(key=lambda x: int(x[:-4]))
    # a = sorted(a, key=lambda x: int(x[:-4]), reverse=True)
    print(a)
    for file in a:
        file = './out/' + file
        #
        img = Image.open(file).convert('RGB')
        arr = np.array(img)
        arr = changecolor(arr)
        frame = Image.fromarray(arr)
        frame.save(file)
        imgs.append(frame)

    # 把图片流重新成成GIF动图
    imgs[0].save(new_filename, save_all=True, append_images=imgs[1:])
    # time.sleep(0.5)
    result = post_file(new_filename)
    return result
Beispiel #9
0
def get_monkey_text_bytes(text) -> Union[io.BytesIO, BinaryIO]:
    image = Image.open(MONKEY_IMAGE_PATH)
    frames = []
    for frame in ImageSequence.Iterator(image):
        frame = frame.convert("RGB")
        image_draw = ImageDraw.Draw(frame)
        font = ImageFont.truetype(FONT_PATH, size=30)

        # Divide lines by text width
        lines = text_wrap(text, font, image.size[0])
        # Get line height with a plus
        line_height = font.getsize("hg")[1] + 5

        # Get the starting y point for the first line
        y = image.size[1] - (line_height * len(lines))

        for line in lines:
            w, _ = image_draw.textsize(line, font=font)
            image_draw.text(
                (((image.size[0] - w) / 2), y),
                line,
                font=font,
                fill=(255, 255, 255),
            )

            # Increase y by line height for the next line
            y = y + line_height

        frames.append(frame)

    monkey_bytes = io.BytesIO()
    monkey_bytes.name = "monkey.gif"

    frames[0].save(
        monkey_bytes,
        format="GIF",
        save_all=True,
        append_images=frames[1:],
        transparency=True,
        optimize=False,
    )

    monkey_bytes.seek(0)
    return monkey_bytes
Beispiel #10
0
def wallify_gif_image(
    image: Image.Image, width: int, height: int, *, name: str = None
) -> Tuple[list, BytesIO]:
    """
    Wallify a gif image
    :param image: The base Image
    :param width: Width of the wall (Number of images)
    :param height: Height of the Wall (Number of images)
    :param name: Name to use in example file, defaults to None (uses '_')
    :return: Tuple of a list of Image frames and the example file
    """
    images = []

    factors = get_wallify_factors(image.size, (width, height))

    (
        (new_width, new_height),
        (num_of_rows, num_of_columns),
        (emoji_width, emoji_height),
    ) = factors

    for row in range(num_of_rows):
        for column in range(num_of_columns):
            frames = []

            for page in ImageSequence.Iterator(image):
                page = page.resize((new_width, new_height))
                frames.append(
                    page.crop(
                        (
                            column * emoji_width,
                            row * emoji_height,
                            (column * emoji_width) + emoji_width,
                            (row * emoji_height) + emoji_height,
                        )
                    )
                )

            images.append(frames)

    wallify_example = get_wallify_example_file((num_of_rows, num_of_columns), name)

    return images, wallify_example
Beispiel #11
0
 def make_wheeze_gif(self, template: Image, avatar: Image) -> BytesIO:
     gif_list = [frame.copy() for frame in ImageSequence.Iterator(avatar)]
     img_list = []
     num = 0
     temp = None
     for frame in gif_list:
         template = template.convert("RGBA")
         frame = frame.convert("RGBA")
         template.paste(frame, (60, 470), frame)
         img_list.append(template)
         num += 1
         temp = BytesIO()
         template.save(
             temp, format="GIF", save_all=True, append_images=img_list, duration=0, loop=0
         )
         temp.name = "beautiful.gif"
         if sys.getsizeof(temp) < 8000000 and sys.getsizeof(temp) > 7000000:
             break
     return temp
Beispiel #12
0
def test_apng_reading(tmp_path, test_images):
    # create a APNG
    img = iio.v3.imread(test_images / "newtonscradle.gif", index=None)
    iio.v3.imwrite(tmp_path / "test.apng", img)

    # test single image read
    with Image.open(tmp_path / "test.apng") as im:
        im.seek(8)
        expected = np.asarray(im)
    actual = iio.v3.imread(tmp_path / "test.apng", index=8)
    assert np.allclose(actual, expected)

    # test reading all frames
    all_frames = iio.v3.imread(tmp_path / "test.apng", index=None)
    with Image.open(tmp_path / "test.apng") as im:
        for idx, frame in enumerate(ImageSequence.Iterator(im)):
            expected = np.asarray(frame)
            actual = all_frames[idx]
            assert np.allclose(actual, expected)
Beispiel #13
0
def copper():
    org_img = Image.open("22.gif")
    new_img = Image.new('RGB', org_img.size, "black")
    new_img_draw = ImageDraw.Draw(new_img)
    x = 0
    y = 0
    # iter over frames
    for s in ImageSequence.Iterator(org_img):
        left, upper, right, lower = org_img.getbbox()
        dx = left - 100
        dy = upper - 100
        x += dx
        y += dy
        if dx == dy == 0:
            x += 20
            y += 30
        new_img_draw.point((x, y))

    new_img.save("22-1.png")
Beispiel #14
0
    def __init__(self, root, canvas, x, y, app):
        self.root = root
        self.canvas = canvas

        self.sequence = [
            ImageTk.PhotoImage(img) for img in ImageSequence.Iterator(
                Image.open("resources/player2winner.gif"))
        ]

        self.image = self.canvas.create_image(x,
                                              y,
                                              image=self.sequence[0],
                                              anchor=NW)
        self.after = 67
        self.animating = True
        self.pausing = True
        self.canvas.itemconfig(self.image, state="hidden")
        self.sound = pygame.mixer.Sound("resources/playerwinner.wav")
        self.sound.set_volume(app.musicVolume / 100)
Beispiel #15
0
async def check_image(image, modifier, method):
    try:
        modifier_converter = MODIFIERS[modifier]
    except KeyError:
        raise RuntimeError('Invalid image modifier.')

    with Image.open(io.BytesIO(image)) as img:
        if img.format == "GIF":
            total = [0, 0, 0, 0]
            count = 0

            for frame in ImageSequence.Iterator(img):
                f = frame.resize((round(img.width / 3), round(img.height / 3)))
                values = color_ratios(f, modifier_converter['colors'])
                for i in range(4):
                    total[i] += values[i]
                count += 1

            ratios = [0, 0, 0, 0]
            for i in range(4):
                ratios[i] = round(10000 * total[i] / count) / 100

            passed = ratios[3] <= 10

        else:
            img = img.resize((round(img.width / 3), round(img.height / 3)))
            values = color_ratios(img, modifier_converter['colors'])

            ratios = [0, 0, 0, 0]
            for i in range(4):
                ratios[i] = round(10000 * values[i]) / 100

            passed = ratios[3] <= 10

    colors = []
    for i in range(3):
        colors.append({
            'name': modifier_converter['color_names'][i],
            'ratio': ratios[i]
        })
    colors.append({'name': 'Non-Halloween', 'ratio': ratios[3]})
    data = {'passed': passed, 'colors': colors}
    return data
Beispiel #16
0
    def handle(self, path):
        """Handle image with path
        :path: <str>
        """
        try:
            img = Image.open(path)
        except IOError as e:
            print(e)
            return False

        frames = [
            frame.convert('RGBA') for frame in ImageSequence.Iterator(img)
        ]
        for index in range(len(frames)):
            frames[index] = self._handleFrame(frames[index],
                                              index / len(frames))

        self._frames = frames
        return True
Beispiel #17
0
def process_gif(image, filename, res, output, name, ext):
    frames = ImageSequence.Iterator(image)

    def thumbnails(frames_):
        for frame in frames_:
            thumbnail = frame.copy()
            thumbnail.thumbnail(res, resampler)
            yield thumbnail

    frames = thumbnails(frames)
    image_out = next(frames)  # get the first frame
    image_out.info = image.info  # copy image info
    if not args.organize:
        filename = name + (' - %dx%d' % image_out.size) + ext
    image_out.save(  # save GIF and append rest of the frames to it
        path.join(output, filename),
        save_all=True,
        append_images=list(frames),
        optimize=True)
Beispiel #18
0
 def resize_gif(self, size: int, image: str) -> discord.File:
     img_list = []
     with Image.open(image) as im:
         if size <= 0:
             size = 1
         length, width = (16 * size, 16 * size)
         start_list = [frame.copy() for frame in ImageSequence.Iterator(im)]
         for frame in start_list:
             frame.thumbnail((length, width), Image.ANTIALIAS)
             img_list.append(frame)
     byte_array = BytesIO()
     img_list[0].save(byte_array,
                      format="GIF",
                      save_all=True,
                      append_images=img_list,
                      duration=0,
                      loop=0)
     byte_array.seek(0)
     return discord.File(byte_array, filename="resize.gif")
Beispiel #19
0
    def get_image(self, path):
        #global tkpi
        image = Image.open(path)
        
#        self.image = image.resize((self.tk.winfo_screenwidth(), self.tk.winfo_screenheight()))
#        self.tk.geometry('%dx%d' % (image.size[0], image.size[1]))        print("Image Type: "+str(path))
#        self.tkpi = ImageTk.PhotoImage(image)
#
#        label = tk.Label(self.tk, image=self.tkpi)
#        label.place(x=0,y=0,width=image.size[0], height=image.size[1])
         
        self.imagesequence = ImageSequence.Iterator(Image.open(path))
        
        self.imagesequence = [ImageTk.PhotoImage(image.resize((self.tk.winfo_screenwidth(), self.tk.winfo_screenheight()))) for image in self.imagesequence]
        # self.imagesequence = [ImageTk.PhotoImage(image) for image in self.imagesequence]

        self.image = self.canvas.create_image(self.tk.winfo_screenwidth()/2,self.tk.winfo_screenheight()/2, image=self.imagesequence[0])
        
        self.animate(0)
Beispiel #20
0
def freme_binary(img):
    try:
        img = Image.open(img)
    except IOError:
        print("Fail to open image")

    cur = 1
    for frame in ImageSequence.Iterator(img):
        width, height = frame.size
        image_list = []
        for x in range(height):
            px_line = []
            for y in range(width):
                px = frame.getpixel((y, x))
                px_line.append(px)
            image_list.append(px_line)
        print_to_txt(image_list, cur)
        # print(image_list)
        cur += 1
Beispiel #21
0
def add_text(text, img_file='images/breakingbad.gif'):
    im = Image.open(img_file)

    frames = []
    durations = []

    for frame in ImageSequence.Iterator(im):
        durations.append(frame.info['duration'])
        frame = ImageOps.expand(frame.convert('RGB'), (0, 45, 0, 0), 'white')

        d = ImageDraw.Draw(frame)
        font_size = 33
        font = ImageFont.truetype("fonts/arial.ttf", font_size)
        w, h = d.textsize(text, font=font)
        while (w > frame.size[0] * 0.9):
            if font_size > 3:
                font_size -= 3
                font = ImageFont.truetype("fonts/arial.ttf", font_size)
                w, h = d.textsize(text, font=font)
            else:
                break

        d.text(((frame.size[0] - w) / 2, (45 - h) / 2),
               text,
               font=font,
               fill='black')
        del d

        b = io.BytesIO()
        frame.save(b, format="GIF")
        frame = Image.open(b)

        frames.append(frame)

    tmpfile = io.BytesIO()
    frames[0].save(tmpfile,
                   save_all=True,
                   append_images=frames[1:],
                   format="GIF",
                   duration=durations,
                   loop=0)
    tmpfile.seek(0)
    return tmpfile
    def __init__(self, parent, controller):
        self.controller = controller

        Frame.__init__(self, parent)
        self.bind("<<show_frame>>", self.facerec)

        def animates(self, counters):
            canvas.itemconfig(image, image=sequence[counters])
            parent.after(250, lambda: animates(self, (counters + 1) % len(sequence)))

        canvas = Canvas(self, width=400, height=400)
        canvas.pack()
        sequence = [ImageTk.PhotoImage(img)
                    for img in ImageSequence.Iterator(
                Image.open(r'resource_images/face_rec.gif')
            )]
        image = canvas.create_image(200, 200, image=sequence[0])
        animates(self, 1)
        label = Label(self, text="Position Camera Face Upward",background='green', font='times 15 bold').pack(pady=10, padx=10)
Beispiel #23
0
    async def resize(self, context, imageType, imageUrl, width, height):
        if (not context.message.author.guild_permissions.administrator):
            await context.send('```You do not have permission to use this```')
            return
        size = (int(width), int(height))
        if (size[0] > 2000 or size[1] > 2000):
            await context.send(
                "*Pebble deems resolution is too big and rolls away*. <a:PebbleIconAnimation:746859796585513040>"
            )
            return

        response = requests.get(imageUrl)
        img = Image.open(BytesIO(response.content))

        if (imageType == 'png'):
            img = img.resize(size)
            img.save('resize.{}'.format('png'))
            await context.send(file=discord.File('resize.{}'.format('png')))
        elif (imageType == 'gif'):

            frames = ImageSequence.Iterator(img)

            def thumbnails(frames):
                for frame in frames:
                    thumbnail = frame.copy()
                    thumbnail.thumbnail(size)
                    yield thumbnail

            frames = thumbnails(frames)

            # Save output
            om = next(frames)  # Handle first frame separately
            om.info = img.info  # Copy sequence info
            om.save("resize.gif",
                    save_all=True,
                    append_images=list(frames),
                    loop=0)
            await context.send(file=discord.File('resize.{}'.format('gif')))
        else:
            await context.send(
                "*Pebble deems your image type invalid and rolls away*. <a:PebbleIconAnimation:746859796585513040>"
            )
            return
def ensamblajeWindow(e):
    newWindow = tk.Toplevel(root)
    newWindow.geometry("854x480")
    newWindow.title("Ensamblaje")

    def animateBTN2(cvs, prnt, sq, img, counter, speed):
        cvs.itemconfig(img, image=sq[counter])
        prnt.after(
            speed, lambda: animateBTN2(cvs, prnt, sq, img,
                                       (counter + 1) % len(sq), speed))

    c6 = tk.Canvas(newWindow, bd=0, highlightthickness=0)
    c6.place(relx=0, rely=0, relwidth=1, relheight=1)
    sequence5 = [
        ImageTk.PhotoImage(img) for img in ImageSequence.Iterator(
            Image.open(AbsolutePath.resource_path('gifs/sample2.gif')))
    ]
    c6IMG = c6.create_image(0, 0, anchor="nw", image=sequence5[0])
    animateBTN2(c6, c6, sequence5, c6IMG, 0, 3000)
Beispiel #25
0
    def LoadingWheel(self, Ox, Oy):
        """ LoadingWheel
        Description:
            Metoda care creeaza loading wheel-ul

        Parameters:
            Ox (int): Coordonata de pe axa Ox
            Oy (int): Coordonata de pe axa Oy

        Returns:

        """

        self.sequence = [ImageTk.PhotoImage(img)
                         for img in ImageSequence.Iterator(
                Image.open(
                    r'LoadingWheel\ezgif.com-resize_155_82.gif'))]
        self.image = self.canvas.create_image(Ox, Oy, image=self.sequence[0], anchor='nw')
        self.animate(1)
Beispiel #26
0
 def get_gif_frames(self, path):
     """Returns percentage of a GIF's frames as local file paths"""
     frame_percentage = .25
     frame_paths = []
     im = Image.open(path)
     frame_count = 0
     image_name = path.split('.')[0]
     for frame in ImageSequence.Iterator(im):
         frame_path = image_name + "-%s.gif" % frame_count
         frame.save(frame_path)
         frame_paths.append(frame_path)
         frame_count += 1
     denominator = math.floor(frame_count * frame_percentage)
     frames_to_check = [
         path for idx, path in enumerate(frame_paths)
         if idx % denominator == 0
     ]
     frames_to_check.append(frame_paths[-1])
     return frames_to_check
Beispiel #27
0
def start(files):
    strip = Adafruit_NeoPixel(LED_COUNT, LED_PIN, LED_FREQ_HZ, LED_DMA,
                              LED_INVERT, LED_BRIGHTNESS)
    strip.begin()

    fn = files[0]

    path, fname = os.path.split(fn)

    im = Image.open(fn)

    dur = im.info['duration']

    frames = [frame.copy() for frame in ImageSequence.Iterator(im)]

    frames8 = []

    for frame in frames:
        frame = frame.convert('RGB')
        if fname == "heart.gif":
            frame = frame.crop((50, 50, 450, 450))
            frame = frame.resize((8, 8))

        elif fname == "lemming.gif":
            frame = frame.crop((28, 16, 60, 60))
            frame = frame.resize((8, 8), Image.BICUBIC)
        else:
            frame = frame.resize((8, 8), Image.BICUBIC)

        frames8.append(frame)

    while 1:
        for frame in frames8:
            for y in range(frame.size[1]):
                for x in range(frame.size[0]):
                    r, g, b = frame.getpixel((x, y))
                    if y % 2 == 0:
                        i = y * 8 + x
                    else:
                        i = (y + 1) * 8 - x - 1
                    strip.setPixelColor(i, Color(g, r, b))
            strip.show()
            time.sleep(dur / 1000.)
Beispiel #28
0
 def __init__(self, parent):
     self.parent = parent
     self.sequence = [
         ImageTk.PhotoImage(img) for img in ImageSequence.Iterator(
             Image.open('./../work/Thumbails/candy.flv_thumbs_0000.gif'))
     ]
     self.img_width = self.sequence[0].width()
     self.img_height = self.sequence[0].height()
     print("w x h : {} x {}".format(self.img_width, self.img_width))
     self.canvas = tkinter.Canvas(self.parent,
                                  width=self.img_width,
                                  height=self.img_height,
                                  bg="yellow")
     self.canvas.pack()
     self.image = self.canvas.create_image(self.img_width / 2,
                                           self.img_height / 2,
                                           image=self.sequence[0])
     self.animating = True
     self.animate(0)
Beispiel #29
0
def read_image2RGBbytesFrom(image_path):
    with BytesIO() as output:
        try:
            with Image.open(image_path) as img:
                frames = [
                    frame.copy() for frame in ImageSequence.Iterator(img)
                ]
                frameCount = len(frames)
                if frameCount < 5:
                    temImg = frames[frameCount // 2]
                    temImg.convert('RGB').save(output, 'JPEG')
                else:
                    temImg = frames[frameCount - 4]
                    temImg.convert('RGB').save(output, 'JPEG')
                image_data = output.getvalue()
        except:
            print("读取图片失败")
            return None
    return image_data
    def render_animation(self, ani_path, loops=5):
        """Renders animated images on the matrix.
           Args:
             ani_path: resolvable path to the animation
             loops: how many times to loop the image, 5 by default.
        """
        im = Image.open(ani_path)
        if not im.is_animated:
            raise Exception("Not an animation")
        ani = []

        # translate animation.
        for frame in ImageSequence.Iterator(im):
            ani.append(self.__rgb_translate(frame))

        # Queue the frames
        for loop in xrange(loops):
            for frame in ani:
                self.next_frame(frame)