Beispiel #1
0
def write_main_text(img: Image.Image, text: str, font: ImageFont.ImageFont,
                    end_y_heading: int, line_spacing: int) -> None:
    """Inserts the undertitles into the image.

    Args:
        img (Image.Image): The image into which undertitles will be inserted.
        text (str): The text to be inserted.
        font (ImageFont.ImageFont): The font used for the inserted text.
        end_y_heading (int): The lowest y of the heading.
        line_spacing (int, optional): Spacing between lines. Defaults to 30.

    Returns:
        Image.Image: The image into which undertitles are inserted.
    """
    img_width, img_height = img.size
    draw = ImageDraw.Draw(img)

    # start_y = end_y_heading + line_spacing
    # TODO hier start y einsetzen
    start_y = calc_start_y_undertitles(img, text, font, end_y_heading,
                                       line_spacing, None) + end_y_heading
    font_width, font_height = font.getsize(text)

    pattern = pattern_2nd_text(text, img_width, font)
    for vert_start, line in pattern:
        draw_pos = (vert_start, start_y)
        draw.text(draw_pos, line, (0, ) * 3, font)
        start_y += font_height + line_spacing
Beispiel #2
0
def wrap_font_text(font: ImageFont.ImageFont, text: str,
                   max_width: int) -> str:
    wrapper = TextWrapper()
    chunks = wrapper._split_chunks(text)

    lines: List[List[str]] = []
    cur_line: List[str] = []
    cur_line_width = 0

    for chunk in chunks:
        width, _ = font.getsize(chunk)

        # If this chunk makes our line too long...
        if cur_line_width + width > max_width:
            # Special case: a single chunk that's too long to fit on one line.
            # In that case just use that chunk as a line by itself, otherwise
            # we'll enter an infinate loop here.
            if cur_line_width == 0:
                lines.append([chunk])
                cur_line = []
                cur_line_width = 0
                continue

            lines.append(cur_line)
            cur_line = [] if chunk.isspace() else [chunk]
            cur_line_width = width

        else:
            cur_line.append(chunk)
            cur_line_width += width

    lines.append(cur_line)

    return "\n".join("".join(line).strip() for line in lines).strip()
Beispiel #3
0
def write_header(img: Image.Image,
                 text: str,
                 font: ImageFont.ImageFont,
                 height_map_part: int,
                 frame_width: int,
                 adjustment: int = -150) -> int:
    """Inserts the header into the image.

    Args:
        img (Image.Image): The image where the header will be inserted.
        text (str): The text to be inserted.
        font (ImageFont.ImageFont): The font used for the heading.
        height_map_part (int): The height of the raw map.
        frame_width (int): The width of the frame.
        adjustment (int, optional): Adjustment to the height. Defaults to -150.

    Returns:
        int: The lowest y position to which the heading reaches.
    """
    draw = ImageDraw.Draw(img)
    start_y_heading = height_map_part + frame_width + adjustment
    draw.text((0, start_y_heading), text, 'black', font)

    _, heading_height = font.getsize(text)
    end_y_heading = start_y_heading + heading_height

    return end_y_heading
def draw_text(image: Image.Image, text: str, text_color: tuple, font: ImageFont.ImageFont = None) -> Image:
    if font is None and os.path.isfile(FONT_DEFAULT):
        font = FONT_DEFAULT
        font_size = int(image.width * 0.07)
        font = ImageFont.truetype(font=font, size=font_size)

    text_width, text_height = font.getsize(text)
    text_position = ((image.width - text_width) / 2, (image.height - text_height) / 2)

    drw = ImageDraw.Draw(image, "RGBA")
    drw.multiline_text(text_position, text, fill=text_color, font=font)
    return image
Beispiel #5
0
def draw_text_relative(draw: ImageDraw.ImageDraw,
                       anchor: Tuple[float, float],
                       text: str,
                       font: ImageFont.ImageFont,
                       xa: float = 0,
                       ya: float = 0,
                       clamp_image: Image.Image = None):
    x, y = anchor
    w, h = font.getsize(text)
    x -= w * xa
    y -= h * ya
    if clamp_image is not None:
        x = max((0, min((clamp_image.width - w, x))))
        y = max((0, min((clamp_image.height - h, y))))
    draw.text((x, y), text, font=font)
Beispiel #6
0
def main(stream_url, image_path, location):
    print(stream_url, image_path, location)

    cfg = ConfigParser()
    cfg.read(str(CFG_PATH))
    token, chat_id = cfg['tg']['token'], cfg['tg']['chat_id']
    password, water = cfg['enc']['password'], cfg['enc']['water']
    ip = IP_RE.findall(stream_url)[0]
    water = '%s %s' % (eip4(ip), water)

    url = 'https://api.telegram.org/bot%s/sendphoto' % token

    data = dict(chat_id=chat_id,
                caption='```%s```' % stream_url,
                parse_mode='Markdown')

    with open(image_path, 'rb') as f:
        img: Image = Image.open(f)
        w, h = img.size

        text = ' '.join(location)
        print(w, h)
        font_size = int(0.04 * min(h, w))
        px = int(0.005 * w)
        py = int(0.002 * h)
        font = ImageFont.truetype(str(FONT_PATH), font_size)
        draw = ImageDraw.Draw(img, 'RGBA')
        _, text_height = draw.textsize('Wg', font)
        water_width, _ = draw.textsize(water, font)

        text_y = h - py - text_height

        draw.rectangle((0, text_y - py, w, h), fill=(0, 0, 0, 160))

        draw.text((px, text_y), text, fill='yellow', font=font)
        draw.text((w - px - water_width, text_y),
                  water,
                  fill=(255, 255, 255, 128),
                  font=font)

        img_byte_arr = io.BytesIO()
        img.save(img_byte_arr, format='PNG')
        img_byte_arr = img_byte_arr.getvalue()

        response = requests.post(url, data=data, files={'photo': img_byte_arr})

    print(response.json())
Beispiel #7
0
def calc_start_y_undertitles(img: Image.Image, undertitles_text: str,
                             undertitles_font: ImageFont.ImageFont,
                             end_y_heading: int, line_spacing: int,
                             town_names: Union[None, List[str]]) -> int:
    """Calculates where to put the undertitles.

    Args:
        img (Image.Image): The image into which the undertitles will be put.
        undertitles_text (str): The undertitle as string.
        undertitles_font (ImageFont.ImageFont): The font of the undertitles.
        end_y_heading (int): The lowest y position of the heading.
        line_spacing (int): The spacing between the lines of the undertitles.
        town_names (Union[None, List[str]]): The names of possible towns.

    Returns:
        int: The y position at which the undertitles to start.
    """
    img_width, img_height = img.size
    empty_height = img_height - end_y_heading

    coats_wanted = town_names is not None
    if coats_wanted:
        pattern = pattern_2nd_text_with_coats(undertitles_text, img,
                                              undertitles_font, line_spacing,
                                              town_names)
        lines = [compile_to_line(line) for _, line, _ in pattern]
    else:
        pattern = pattern_2nd_text(undertitles_text,
                                   img.width,
                                   undertitles_font,
                                   line_dist=line_spacing)
        lines = [line for _, line in pattern]

    num_lines = len(lines)
    num_gaps = num_lines - 1
    _, line_height = undertitles_font.getsize('Tg')

    undertitles_height = line_height * num_lines + line_spacing * num_gaps
    # assert empty_height > undertitles_height
    diff = empty_height - undertitles_height

    return round(diff / 2)
Beispiel #8
0
def get_code(request):
    mode = 'RGD'
    size = (200, 100)

    def _get_color():
        return random.randrange(255)

    def _generate_code():
        source = 'asdjcfboiawuehrbgtfoui21345asdcasdc'
        code = ''
        for i in range(4):
            code += random.choice(source)
        return code

    red = _get_color()
    green = _get_color()
    blue = _get_color()
    color_bg = (red, green, blue)

    image = Image.new(mode=mode, size=size, color=color_bg)
    image_draw = ImageDraw(image, mode=mode)
    image_font = ImageFont.truetype(settings.FONT_PATH, 100)

    verify_code = _generate_code()

    request.session['verify_code'] = verify_code

    for i in range(len(verify_code)):
        image_draw.text(xy=(40 * i, 0), text=verify_code[i], font=image_font)

    for i in range(1000):
        fill = (_get_color(), _get_color(), _get_color())
        xy = (random.randrange(201), random.randrange(100))
        image_draw.point(xy=xy, fill=fill)

    fp = BytesIO()
    image.save(fp, 'png')

    return HttpResponse(fp.getvalue(), content_type='img/png')
Beispiel #9
0
    def rainbow_multiline_text(self,
                               xy: tuple,
                               text: str,
                               fill: list = None,
                               randomise: bool = False,
                               font: ImageFont.ImageFont = None,
                               spacing: int = 4,
                               align: str = "left",
                               alignY: str = "top",
                               text_align: str = "left",
                               stroke_width: int = 0,
                               stroke_fill: tuple = None,
                               embedded_color: bool = None):
        """
        Draws a string of text at the defined position but uses different colours for each letter.

        :param xy: tuple
        :param text: str
        :param fill: list
        :param randomise bool
        :param font: PIL.ImageFont.ImageFont
        :param spacing: int (The number of pixels between lines. (default 4))
        :param align: str (Determines the relative alignment of the text based off of the x co-ord. (this is slightly different to vanilla PIL as anchors are not used in this))
        :param alignY: str (Determines the relative alignment of the text based off of the y co-ord. (this is slightly different to vanilla PIL as anchors are not used in this))
        :param text_align: str (Sets the text align based on its position. (This is similar to align in vanilla PIL except it stays in the same xy position))
        :param stroke_width: int (The width of the text stroke.)
        :param stroke_fill: tuple (Color to use for the text stroke. (if none parsed will use the defined colours))
        :param embedded_color: bool (Whether to use font embedded color glyphs. (COLR or CBDT))
        """

        if embedded_color and self.image.mode not in ("RGB", "RGBA"):
            raise ValueError(
                "Embedded color supported only in RGB and RGBA modes")

        if not font:
            font = ImageDraw.Draw(self.image).getfont()

        x, y = xy
        lines = core.multiline_split(text)
        draw = ImageDraw.Draw(self.image)
        current = 0
        render_size = font.getsize_multiline(text, spacing=spacing)

        if fill is None:
            fill = RAINBOW_DEFAULT

        def next_colour(n):
            n += 1
            return 0 if n == len(fill) else n

        if align != "left":
            x -= render_size[0] if align == "right" else 0
            x -= int(render_size[0] / 2) if align == "center" else 0
        if alignY != "top":
            y -= render_size[1] if alignY == "bottom" else 0
            y -= int(render_size[1] / 2) if alignY == "center" else 0

        for line in lines:
            lineX = x
            if text_align != "left":
                lineX += render_size[0] - font.getsize(
                    line)[0] if text_align == "right" else 0
                lineX += int((render_size[0] - font.getsize(line)[0]) /
                             2) if text_align == "center" else 0

            for letter in list(line):
                draw.text((lineX, y),
                          letter,
                          font=font,
                          fill=choice(fill) if randomise else fill[current],
                          stroke_width=stroke_width,
                          stroke_fill=stroke_fill,
                          embedded_color=embedded_color)

                lineX += font.getsize(letter)[0]

                current = next_colour(current)
            y += font.getsize(line)[1] + spacing
Beispiel #10
0
    def rainbow_text(self,
                     xy: tuple,
                     text: str,
                     fill: list = None,
                     randomise: bool = False,
                     font: ImageFont.ImageFont = None,
                     align: str = "left",
                     alignY: str = "top",
                     stroke_width: int = 0,
                     stroke_fill: tuple = None,
                     embedded_color: bool = None):
        """
        Draws a string of text at the defined position but uses different colours for each letter.

        :param xy: tuple
        :param text: str
        :param fill: list
        :param randomise bool
        :param font: PIL.ImageFont.ImageFont
        :param align: str
        :param alignY: str
        :param stroke_width: int
        :param stroke_fill: tuple
        :param embedded_color: bool
        """

        if core.multiline_check(text):
            return self.rainbow_multiline_text(xy=xy,
                                               text=text,
                                               fill=fill,
                                               randomise=randomise,
                                               font=font,
                                               align=align,
                                               alignY=alignY,
                                               stroke_width=stroke_width,
                                               stroke_fill=stroke_fill,
                                               embedded_color=embedded_color)

        if embedded_color and self.image.mode not in ("RGB", "RGBA"):
            raise ValueError(
                "Embedded color supported only in RGB and RGBA modes")

        if not font:
            font = ImageDraw.Draw(self.image).getfont()

        x, y = xy
        if fill is None:
            fill = RAINBOW_DEFAULT
        draw = ImageDraw.Draw(self.image)

        render_size = font.getsize(text)
        if align != "left":
            x -= render_size[0] if align == "right" else 0
            x -= int(render_size[0] / 2) if align == "center" else 0
        if alignY != "top":
            y -= render_size[1] if alignY == "bottom" else 0
            y -= int(render_size[1] / 2) if alignY == "center" else 0

        current = 0
        for letter in list(text):
            draw.text((x, y),
                      letter,
                      font=font,
                      fill=choice(fill) if randomise else fill[current],
                      stroke_width=stroke_width,
                      stroke_fill=stroke_fill,
                      embedded_color=embedded_color)

            x += font.getsize(letter)[0]
            current += 1
            current = 0 if current == len(fill) else current
Beispiel #11
0
def _create_image_for_pair(rows, model_m, pair):
    length = len(rows)
    if length > 10:
        return

    w, h = 480, 480
    distance = 30
    interval = int((w - distance) / (length + 3))  # Интервал между стрелок

    if abs(float(rows[0][1])) > abs(float(rows[length - 1][1])):
        max = float(rows[0][1])

    else:
        max = float(rows[length - 1][1])

    min_value = str(round(rows[-1][1], 2))

    h_scale = h - 80  # ДЛя графиков чтобы оставить место подписи

    for row in rows:
        if (max < 0 and float(row[1]) > 0):
            row[1] = int((float(row[1])) * (h_scale / 2 - 10) / max * (-1))
        elif (max < 0 and float(row[1]) < 0):
            row[1] = int((float(row[1])) * (h_scale / 2 - 10) / max * (-1))
        else:
            row[1] = int((float(row[1])) * (h_scale / 2 - 10) / max)

    im = Image.new('RGB', (w, h), (195, 197, 200))
    na = np.array(im)

    h_begin = int(h_scale / 2)
    # Оси
    na = cv2.arrowedLine(na, (3, h_begin), (w - 5, h_begin), (0, 0, 0), 4)
    na = cv2.arrowedLine(na, (distance, h - 50), (distance, 5), (0, 0, 0), 4)

    h_end = int(h_scale / 2 - (rows[-1][1]))
    na = cv2.line(na, (15, h_end), (45, h_end), (0, 0, 0), 4)

    distance += interval * 2
    for row in rows:

        h_end = int(h_scale / 2 - (row[1]))
        na = cv2.arrowedLine(na, (distance, h_begin), (distance, h_end),
                             (0, 0, 0), 4)
        distance += interval

    path = f'{MEDIA_ROOT}/files/models/{str(model_m.model.id)}/original_snod/modification/{str(model_m.id)}/images/{str(pair.id)}.png'
    Image.fromarray(na).save(path)

    # Делаем подписи
    img = Image.open(path)
    idraw = ImageDraw.Draw(img)
    path_font = f'{MEDIA_ROOT}/fonts/9041.ttf'
    font = ImageFont.truetype(path_font, size=18)

    distance = 30
    distance += interval * 2
    for row in rows:
        text = str((row[0]) + 1)
        if float(row[1]) > 0:
            idraw.text((distance, int(h_scale / 2 + 50)),
                       text,
                       font=font,
                       fill='#000000')
        elif float(row[1]) == 0:
            idraw.ellipse(
                [distance - 10, h_begin - 10, distance + 10, h_begin + 10],
                fill='#000000')
            idraw.text((distance, int(h_scale / 2 - 50)),
                       text,
                       font=font,
                       fill='#000000')
        else:
            idraw.text((distance, int(h_scale / 2 - 50)),
                       text,
                       font=font,
                       fill='#000000')
        distance += interval

    text = pair.option_1.name
    length = len(text) * 9
    idraw.text((w - 15 - length, h - 40),
               pair.option_2.name,
               font=font,
               fill='#000000')
    idraw.text((15, h - 40), text, font=font, fill='#000000')

    idraw.text((w - 45, h / 2), 'Ox', font=font, fill='#000000')
    idraw.text((60, 15), 'Oy', font=font, fill='#000000')

    # Подписываем риски
    h_end = int(h_scale / 2 - (rows[-1][1]))

    idraw.text((45, h_end), min_value, font=font, fill='#000000')

    img.save(path)
Beispiel #12
0
def write_main_text_with_heraldry(
    img: Image.Image,
    text: str,
    font: ImageFont.ImageFont,
    line_spacing: int,
    town_names: List[str],
    end_y_heading: int,  # The y position at which the heading ends.
    coat_text_gap: int = 15) -> None:
    """Inserts the undertitles into the image uncluding heraldry.

    Args:
        img (Image.Image): The image into which undertitles will be inserted.
        text (str): The text to be inserted.
        font (ImageFont.ImageFont): The font used for the inserted text.
        line_spacing (int): Spacing between lines.
        town_names (List[str]): The town names for which coats are provided.
        end_y_heading (int): The lowest y position of the heading.
    """
    _, font_height = font.getsize('Tg')

    # start_y = end_y_heading + line_spacing TODO hier start_y einsetzen
    start_y = calc_start_y_undertitles(img, text, font, end_y_heading,
                                       line_spacing,
                                       town_names) + end_y_heading
    complete_text_pattern = pattern_2nd_text_with_coats(
        text, img, font, line_spacing, town_names)

    added_width_of_line_by_coat = []
    for _, line_pattern, _ in complete_text_pattern:
        line = compile_to_line(line_pattern)
        added_width_in_this_line = 0
        for line_element in line:
            if type(line_element) is not str:
                element_width, _ = proportional_size(font_height, line_element)
                added_width_in_this_line += element_width + 2 * coat_text_gap

        added_width_of_line_by_coat.append(added_width_in_this_line)

    for iter_num, (start_x, line_pattern,
                   num_coats) in enumerate(complete_text_pattern):
        added_coat_width = added_width_of_line_by_coat[iter_num]
        print(max(added_width_of_line_by_coat) - added_coat_width)
        start_x += round(
            (max(added_width_of_line_by_coat) - added_coat_width) / 2)
        line = compile_to_line(line_pattern)
        drawing = ImageDraw.Draw(img)

        for i, line_element in enumerate(line):
            if type(line_element) is str:
                drawing.text((start_x, start_y),
                             line_element,
                             font=font,
                             fill='black')
                element_width, _ = font.getsize(line_element)
                start_x += element_width
            else:
                start_x += coat_text_gap if not i == 0 else 0

                element_width, element_height = proportional_size(
                    font_height, line_element)
                line_element.thumbnail((element_width, element_height))
                img.paste(line_element, (start_x, start_y), line_element)

                start_x += element_width + coat_text_gap

        start_y += font_height + line_spacing
#coding=utf-8
from PIL.ImageFont import ImageFont
from gevent.libev.corecext import sys

import HyperLPRLite as pr
import cv2
import numpy as np
import imp
imp.reload(sys)
fontC = ImageFont.truetype("Font/platech.ttf", 14, 0)

# 从本地读取图片并做识别,返回所有识别到车牌的【识别结果,置信度,位置】
# smallest_confidence:最小置信度
def recognize_plate(image, smallest_confidence = 0.7):
    model = pr.LPR("model/cascade.xml", "model/model12.h5", "model/ocr_plate_all_gru.h5") #训练好的模型参数
    model.SimpleRecognizePlateByE2E(image)
    return_all_plate = []
    for pstr,confidence,rect in model.SimpleRecognizePlateByE2E(image):
        if confidence>smallest_confidence:
            return_all_plate.append([pstr,confidence,rect])  #返回车牌号,车牌位置,置信度
    return return_all_plate

test_image = cv2.imread("Images/16.jpg") #读入图片
print(recognize_plate(test_image)) #打印结果,车牌号,车牌位置,置信度