pythonimagecalculatordrawmicropython

HP Prime Draw Image with Python


I would like to play a video (with python) on my HP Prime G2. I know this sounds stupid but please.

So, I already converted the video to a list of pixels but I realise that drawing the pixels one by one on the screen is VERY VERY slow. So I'm wondering if there is any faster way of drawing a whole image (best solution but less probable) or a method, function or something like that to speedup the drawing process. I can draw a single pixel or a rectangle.

Here are my encode/decode python scripts if anyone is interested:

encode.py

import cv2
import numpy as np

COLOR_THRESHOLD = 60
PIXEL_SIZE = 2
WIDTH, HEIGHT = 320 // PIXEL_SIZE, 240 // PIXEL_SIZE

video = cv2.VideoCapture(r'./video.mp4')

def is_close_to_black(pixel, threshold=20):
    # Check if any of the RGB values are below the threshold
    return all(component < threshold for component in pixel)

def ColorDistance(rgb1, rgb2):
    return np.linalg.norm(np.array(rgb1) - np.array(rgb2))

def rgb_to_hex(rgb):
    hex_color = f'{rgb[0]:02x}{rgb[1]:02x}{rgb[2]:02x}'
    
    return hex_color.upper()

with open('video.txt', 'w') as file:  # Use 'w' for writing text data
    currentframe = 0
    lastframe = np.zeros((HEIGHT, WIDTH, 3), dtype=int)

    while True:
        ret, frame = video.read()
        if not ret:
            break

        # Resize frame to match the defined WIDTH and HEIGHT
        frame = cv2.resize(frame, (WIDTH, HEIGHT))

        lines = []
        for i, row in enumerate(frame):
            filtered_pixels = [pixel for pixel in row if not is_close_to_black(pixel)]
            if not filtered_pixels:
                lines.append('0')
            else:
                row_result = []
                for ii, pixel in enumerate(row):
                    if ColorDistance(lastframe[i][ii], pixel) < COLOR_THRESHOLD:
                        row_result.append('?')
                    else:
                        row_result.append(rgb_to_hex(pixel))

                # Format the line for the current row
                line = ','.join(row_result)
                lines.append(line)

        # Write the lines to the file
        file.write(';'.join(lines) + '\n')

        # Update the lastframe with the current frame
        lastframe = frame.copy()

        currentframe += 1
        print('Done with frame ' + str(currentframe))

video.release()

decode.py

# PYTHON EXPORT giffer()


from graphic import draw_rectangle

PIXEL_SIZE = 2
WIDTH, HEIGHT = 320 // PIXEL_SIZE, 240 // PIXEL_SIZE

def hex_to_rgb(hex_color):
    rgb = tuple(int(hex_color[i:i+2], 16) for i in (0, 2, 4))
    
    return rgb

def process_line(line, y):
    if line.strip() == '0':
        draw_rectangle(0, 0, WIDTH * PIXEL_SIZE, PIXEL_SIZE, [0, 0, 0])
        return

    colors = line.strip().split(',')
    x = 0
    while x < len(colors):
        if colors[x] == '?':
            x += 1
            continue
            
        current_color = hex_to_rgb(colors[x])
        
        start_x = x
        # Find the length of the current run of the same color or '?'
        while x < len(colors) and (colors[x] == '?' or colors[x] == colors[start_x]):
            x += 1
        end_x = x

        # Draw the combined rectangle
        draw_rectangle(start_x * PIXEL_SIZE, y * PIXEL_SIZE, (end_x - start_x) * PIXEL_SIZE, PIXEL_SIZE, [current_color[2], current_color[1], current_color[0]])


def process_frame(frame):
    y = 0
    
    for line in frame.split(';'):
        process_line(line, y)

        if y == HEIGHT:
            y = 0
        else:
            y += 1

FILENAME = 'video' # input('File ID: ')
# Open the video file for reading in text mode ('r')

draw_rectangle(0, 0, WIDTH * PIXEL_SIZE, HEIGHT * PIXEL_SIZE, [0, 0, 0])
with open('../videos.hpappdir/' + FILENAME + '.txt', 'r', encoding='utf-8') as f:
    for line in f:
        process_frame(line)

# end

Solution

  • You can store files (like images) inside applications on the HP Prime.
    Using the command AFiles(filename) inside of an application script lets you access those files.
    By using G1(or G2-G9) = AFiles(filename) and then P_BLITing the image you stored in G1 to G0, you will have the entire image instantly drawn for you.
    So, pass your video through the encode.py script you've written, write a script to go through each frame and display it, and you should be good.

    I highly recommend looking through your calculator's help system - there's a lot of useful information there.

    Note - I do have a script that turns MP4s into videos for the calculator, but it is partially AI written (the encoding part) and so I cannot put it here.