Use Python to complete the once popular image to symbol image, GIF image to character GIF animation operation of the whole network

preface

Over the past few years, I have been struggling in the it industry. Along the way, many have summarized some high-frequency interviews in the python industry. I see most of the new blood in the industry, and I still have all kinds of difficult questions for the answers to all kinds of interview questions or collection

Therefore, I developed an interview dictionary myself, hoping to help everyone, and also hope that more Python newcomers can really join the industry, so that Python fire does not just stay in advertising.

Wechat applet search: Python interview dictionary

Or follow the original personal blog: https://lienze.tech

You can also focus on WeChat official account and send all kinds of interesting technical articles at random: Python programming learning.

Image to character

  1. The basic method is constructed to convert the gray value corresponding to the pixel into characters that can be represented
  2. Image content analysis and conversion to character content
  3. The character content is converted into pixels and written into the image
  4. gif is parsed into individual pictures of each frame, which are processed in the above steps
  5. The processed individual images are combined into a gif

Essential concepts

  • Grayscale value: the color depth of the midpoint of a black-and-white image, generally ranging from 0 to 255, 255 for white and 0 for black, so a black-and-white image is also called a grayscale image
  • Alpha channel value: generally used as opacity parameter. If the alpha channel value of a pixel is 0%, it is completely transparent (that is, invisible), while a value of 100% means a completely opaque pixel (traditional digital image)

Gray value character mapping

For each gray value, we will have a corresponding ascii character corresponding to it. The brightness is determined by the space occupied by the character. The higher the gray value is, the lower the gray value is, and the darker it is

Gray value calculation formula: 0.299 * R + 0.587 * G + 0.144 * B

def gray2char(r, g, b, alpha=256):
    '''
    according to RGBA Value to calculate the gray value and return the character corresponding to the brightness
    '''
    _ = list("$@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/\|()1{}[]?-_+~<>i!lI;:,\"^`'. ")
    char_length = len(_)  # Character sequence length
    proportion = 255 / char_length  # The total gray value corresponds to the list index range
    gray = 0.2126 * r + 0.7152 * g + 0.0722 * b  # Calculation formula of gray value and rgb
    
    return _[int(gray / proportion) - 1]  # Returns the character corresponding to the current gray value

The image is parsed into characters

By analyzing the image, we can get the rgb color value of each pixel of the image, and convert the color value into the gray value. Using the gray value character function, we can get the character corresponding to this pixel

Note that the width and height of characters and pixels are different. A character is much larger than a character. Therefore, in the process of processing an image, the width and height must first be cost-effective. Generally, the width and height of a character are 6:1 And 11:1 for a pixel

def image2text(path):
    '''
    Analyze the image
    @path: Image path
    '''
    img = Image.open(path).convert('RGB')  # Open image
    pic_width, pic_height = img.width, img.height  # Original width and height of image
    width, height = int(pic_width / 6), int(pic_height / 11)  # Character pixel width height conversion
    img = img.resize((width, height), Image.NEAREST)  # The original image is abbreviated, which is suitable for character processing

    # Pixel traversal, gray value character conversion
    content = ''  # Store conversion result characters
    colors = []  # Corresponding to the original color of the coordinate, it is used for coloring the character later

    for h in range(height):  # Start high
        for w in range(width):  # Traverse each row of pixels
            px = img.getpixel((w, h))  # Gets the pixel value of a point
            char = gray2char(px[0], px[1], px[2], px[3] if len(px) > 3 else 256)
            colors.append((px[0], px[1], px[2]))
            content += char
        content += '\n'  # Wrap and append pixels per line \ n
        colors.append((255, 255, 255))  # The color of the future is white
    return content, colors, pic_width, pic_height

Gray character to picture

The returned value of the content obtained through the method in the previous step. Next, you need to store the character content such as the image. Here, you need to open a new image object

Combined with the corresponding color, the characters are written into the corresponding pixel points, and finally stored as pictures. The format can be jpg, which is smaller, the png quality is high, and the result will be large

def text2image(content, colors, pic_width, pic_height, path):
    '''
    Characters are stored as images
    @path: Storage path
    '''
    image = Image.new("RGB", (pic_width, pic_height), (255, 255, 255))  # Create and store image objects
    canvas = ImageDraw.Draw(image)  # Create a canvas that supports painting
    font = ImageFont.load_default().font  # Use default font object directly

    x = 0
    y = 0
    font_w, font_h = font.getsize(content[1])  # Width and height of font

    for i in range(len(content)):  # Traversal character content object
        if content[i] == '\n':  # Traverse to \ n that is the element of the next line
            x = -font_w  # Each initialization of abscissa and ordinate
            y += font_h
            continue
        canvas.text((x, y), content[i], colors[i])  # Write character with color
        x += font_w  # Offsets the pixels of a font
    image.save(path)

Basic test

Convert a basic image into characters and store the result as char.jpg

from PIL import Image, ImageFont, ImageDraw
def main():
    content, colors, pic_width, pic_height = image2text(path="test.jpg")
    text2image(content, colors, pic_width, pic_height, path="char.jpg")

GIF iteration

If you need to process a gif image object, first save each frame of the gif image object separately, and then analyze the image into characters

Then convert the gray-scale characters to pictures, and finally combine the character images into a gif

def gif2image(path):
    '''
    gif Split the image and store the split results in the current working directory temp In the directory
    @path: gif Image location
    '''
    img = Image.open(path)
    work_path = os.getcwd()  # Current working path
    cache_dir = os.path.join(work_path, 'gifTemp')
    if not os.path.exists(cache_dir): # If there is no directory to save individual pictures for each frame, the directory is created
        os.mkdir(cache_dir)
    while True:
        try:
            current = img.tell()  # Get current frame position
            file_name = os.path.join(cache_dir, str(current)+'.png')
            img.save(file_name)
            img.seek(current+1)  # Next frame read
        except EOFError: # GIF read complete
            break
    return current

After that, it can be processed by using the above two image processing methods through the for loop, and the processed image can be saved to the content directory

By traversing the processed character pictures in the content directory, gif splicing them

import imageio
def image2gif(_id, dir_name='content', duration=15 / 130):
    '''
	Convert previously processed characters png Picture combination GIF image
    adopt imageio Module processing merge
    '''
    path = os.path.join(os.getcwd(), dir_name)
    images = []
    for pic_id in range(_id):
        # Traverse to get the id value of each processed character picture
        images.append(imageio.imread(os.path.join(path, '%d.png' % pic_id)))
        # Read data from file
    imageio.mimsave(os.path.join(os.getcwd(), 'fin.gif'),
                    images, duration=duration)

Tags: Python pillow

Posted on Fri, 22 Oct 2021 05:05:46 -0400 by gte806e