Esempio n. 1
0
def getFontSizeByLanguage(string, font, renderer_lib, remove_height_offset=False):
    # get fontsize according to language
    string = cgi.escape(string)                   # Here preparing string to render if any special symbol found then convert into html code for render like(& to &)
    if int(renderer_lib) == 1:
        size = font.getsize(string)
        if remove_height_offset:
            size[1] -= font.getoffset(string)[1]
    else:
        size = pyImage.text(string, dpi=font['normal_font_size'], fontfile=font['normal_font_file']).width, pyImage.text(string, dpi=font['normal_font_size'], fontfile=font['normal_font_file']).height
        x = pyImage.text(string, dpi=font['normal_font_size'], fontfile=font['normal_font_file'])
    return size
Esempio n. 2
0
def renderTextOnImage(text, abs_x, abs_y, background_image, font_file, text_color, font_size, max_width, renderer_lib=1, manage_abs_y=None, manage_abs_x=None, max_height=None, text_resizable=False, hide_extra_text=False, font_family=None, get_details=False, custom_offset=2):
    """
    draw text on image on the basis of height width of a particular box and also make resizable to make best fit to the box
    The variables are used in method:
    text:                      your input text
    abs_x:                     absolute value of axis x to render text from
    abs_y:                     ablsolute value of axis y to render text from
    background_image:          background or base image to render text on it
    font_file:                 font_file to render text with this font
    text_color:                give your custom color for text
    font_size:                 give your own font size
    font_family:               this is font family name of the given font(like "Arial Bold" for Arial_Bold font)
    max_width:                 maximum width for given aria(box width where text is to render)
    renderer_lib:              this is text renderer library if value is "1" then it will use "pillow" lib and if vlaue is "2" then it will use pyvips to render the text
    manage_abs_x and y:        these variables are to manage axis x and y in the given box(hieght, width) on image if vlaue is "center" then text will be in center(with respect y) bellow:
    
    by default manage x and y   manage_x= default and y="center"  manage_x= default and y="down"  manage_x= "center" and y=default     manage_x= "right" and y=default    manage_x= "center" and y="center"
    __________________              ______________________          _____________________            ______________________                 ______________________          ______________________
    |text            |             |                     |         |                     |           |        text         |                |                 text|         |                     |
    |                |             |text                 |         |                     |           |                     |                |                     |         |        text         |
    |________________|             |_____________________|         |text ________________|           |_____________________|                |_____________________|         |_____________________|

    max_height:                 maximun height of the given box
    text_resizable:             It enamble the text resize to fit in the box according to height anbd width
    hide_extra_text:            removes extra text wich is overlapping the given box(in this situation text will not resize automatic)
    get_details:                return only details like(font, text_width, text_total_hieght)
    custom offset:              custom offset between two lines
    """
    
    if font_size is None:
        # There are situation when "font_size" is not known but the maximum height that a text will occupy is known. So with "text_resizable" set to true by default
        # the correct "font_size" will automatically be obtained. And so we make the task easy for the user by ignoring passing an explicit value for it.
        if max_height is None:
            raise Exception("Both 'font_size' and 'max_height' cannot be None")
        if int(renderer_lib) == 1:
            font_size = max_height
        else:
            font_size = max_height*7

    if int(renderer_lib) == 1:
        custom_offset = 0
        # background_image = Image.open(background_image)
        draw = ImageDraw.Draw(background_image)
        font = ImageFont.truetype(font_file, size=font_size)
    else:
        # background_image = pyImage.new_from_file(background_image)
        font = {'normal_font_file': font_file, 'normal_font_size': font_size}
    wrapped_text_array, text_width, text_total_height = getWrappedTextMaxHeightWidth(text, font, max_width, renderer_lib)

    if text_resizable:
        while (text_width > max_width or text_total_height>max_height) and font_size>0:                   # Limiting lines count by decreasing font_size and text_writing_space_width_in_pixel
            if int(renderer_lib) == 1:
                font_size -= 1
                font = ImageFont.truetype(font_file, size=font_size)
            else:
                font_size -= 1
                font.update({'normal_font_size': font_size})
            wrapped_text_array, text_width, text_total_height = getWrappedTextMaxHeightWidth(text, font, max_width, renderer_lib)
            text_total_height = text_total_height + (custom_offset*(len(wrapped_text_array)-1))
    
    if hide_extra_text:
        copy_text = "".join(wrapped_text_array)
        while (text_width > max_width or text_total_height>max_height) and font_size>0:                   # Limiting lines count by decreasing font_size and text_writing_space_width_in_pixel
            text = text[:-1]
            wrapped_text_array, text_width, text_total_height = getWrappedTextMaxHeightWidth(text, font, max_width, renderer_lib)
            text_total_height = text_total_height + (custom_offset*(len(wrapped_text_array)-1))
        if len("".join(wrapped_text_array)) != len(copy_text):
            wrapped_text_array[-1] = wrapped_text_array[-1][:-3] + "..."


    if get_details:
        return font, text_width, text_total_height
    if manage_abs_y and max_height:
        if manage_abs_y=="center" and (max_height-text_total_height)>0:
            abs_y = abs_y + (max_height-text_total_height)/2
        if manage_abs_y=="down" and (max_height-text_total_height)>0:
            abs_y = abs_y + (max_height-text_total_height)
    reset_abs_x = abs_x
    for line in wrapped_text_array:
        if manage_abs_x:
            text_line_width = getFontSizeByLanguage(line, font, renderer_lib)[0]
            if manage_abs_x=="center" and (max_width-text_line_width)>0:
                abs_x = reset_abs_x + (max_width-text_line_width)/2
            if manage_abs_x=="right" and (max_width-text_line_width)>0:
                abs_x = reset_abs_x + (max_width-text_line_width)
        if int(renderer_lib) == 1:
            text_height = font.getsize(line)[1]
            abs_y -= font.getoffset(line)[1]                                                # remove top y_offset value from abs_y to draw text from exact axis(x, y)
            draw.text((abs_x, abs_y), line, fill=text_color, font=font)
            abs_y += text_height + font.getoffset(line)[1]
        else:
            text_height = getFontSizeByLanguage(line, font, renderer_lib)[1]

            line = cgi.escape(line)                                                         # Here preparing string to render if any special symbol found then convert into html code for render like(& to &)
            text = pyImage.text(line, dpi=font['normal_font_size'], font=font_family, fontfile=font_file, align = "centre") 
            # print(font_file, line, font['normal_font_size'])
            # we'll use that as the alpha scale down to make it transparent
            alpha = (text).cast("uchar")
            # make a blue rectangle the same size and tag as srgb
            overlay = text.new_from_image(list(text_color)).copy(interpretation="srgb")
            # attach the alpha
            overlay = overlay.bandjoin(alpha)
            # load an image and composite on the overlay
            background_image = background_image.composite2(overlay, 'over', x = abs_x, y = abs_y)
            abs_y += text_height + custom_offset
    return font, background_image