1##################################################################
2# sjpeg converter script version 1.0
3# Dependencies: (PYTHON-3)
4##################################################################
5SJPG_FILE_FORMAT_VERSION = "V1.00"  #
6JPEG_SPLIT_HEIGHT   = 16
7##################################################################
8import math, os, sys, time
9from PIL import Image
10
11
12OUTPUT_FILE_NAME = ""
13INPUT_FILE       = ""
14
15
16if len(sys.argv) == 2:
17    INPUT_FILE = sys.argv[1]
18    OUTPUT_FILE_NAME = INPUT_FILE.split("/")[-1].split("\\")[-1].split(".")[0]
19else:
20    print("usage:\n\t python " + sys.argv[0] + " input_file.jpg")
21    sys.exit(0)
22
23try:
24    im = Image.open(INPUT_FILE)
25except:
26    print("\nFile not found!")
27    sys.exit(0)
28
29
30print("\nConversion started...\n")
31start_time = time.time()
32width, height = im.size
33
34print("Input:")
35print("\t" + INPUT_FILE)
36print("\tRES = " + str(width) + " x " + str(height) + '\n')
37
38
39lenbuf = []
40block_size = JPEG_SPLIT_HEIGHT;
41spilts = math.ceil(height/block_size)
42
43c_code = '''//LVGL SJPG C ARRAY\n#include "lvgl/lvgl.h"\n\nconst uint8_t ''' + OUTPUT_FILE_NAME + '''_map[] = {\n'''
44
45sjpeg_data = bytearray()
46sjpeg = bytearray()
47
48
49row_remaining = height;
50for i in range(spilts):
51    if row_remaining < block_size:
52        crop = im.crop((0, i*block_size, width, row_remaining + i*block_size))
53    else:
54        crop = im.crop((0, i*block_size, width, block_size + i*block_size))
55
56    row_remaining = row_remaining - block_size;
57    crop.save(str(i)+".jpg", quality=90)
58
59
60
61
62for i in range(spilts):
63    f = open(str(i)+".jpg", "rb")
64    a = f.read()
65    f.close()
66    sjpeg_data = sjpeg_data + a
67    lenbuf.append(len(a))
68
69header = bytearray()
70
71#4 BYTES
72header = header + bytearray("_SJPG__".encode("UTF-8"));
73
74#6 BYTES VERSION
75header = header + bytearray(("\x00" + SJPG_FILE_FORMAT_VERSION + "\x00").encode("UTF-8"));
76
77#WIDTH 2 BYTES
78header = header + width.to_bytes(2, byteorder='little');
79
80#HEIGHT 2 BYTES
81header = header + height.to_bytes(2, byteorder='little');
82
83#NUMBER OF ITEMS 2 BYTES
84header = header + spilts.to_bytes(2, byteorder='little');
85
86#NUMBER OF ITEMS 2 BYTES
87header = header + int(JPEG_SPLIT_HEIGHT).to_bytes(2, byteorder='little');
88
89for item_len in lenbuf:
90    # WIDTH 2 BYTES
91    header = header + item_len.to_bytes(2, byteorder='little');
92
93
94data = bytearray()
95
96sjpeg = header + sjpeg_data;
97
98if 1:
99    for i in range(len(lenbuf)):
100        os.remove(str(i) + ".jpg")
101
102
103f = open(OUTPUT_FILE_NAME+".sjpg","wb");
104f.write(sjpeg)
105f.close()
106
107new_line_threshold = 0
108for i in range(len(sjpeg)):
109    c_code = c_code + "\t" + str(hex(sjpeg[i])) + ","
110    new_line_threshold = new_line_threshold + 1
111    if (new_line_threshold >= 16):
112        c_code = c_code + "\n"
113        new_line_threshold = 0
114
115
116c_code = c_code + "\n};\n\nlv_img_dsc_t "
117c_code = c_code + OUTPUT_FILE_NAME + " = {\n"
118c_code = c_code + "\t.header.always_zero = 0,\n"
119c_code = c_code + "\t.header.w = " + str(width) + ",\n"
120c_code = c_code + "\t.header.h = " + str(height) + ",\n"
121c_code = c_code + "\t.data_size = " + str(len(sjpeg)) + ",\n"
122c_code = c_code + "\t.header.cf = LV_IMG_CF_RAW,\n"
123c_code = c_code + "\t.data = " + OUTPUT_FILE_NAME+"_map" + ",\n};"
124
125
126f = open(OUTPUT_FILE_NAME + '.c', 'w')
127f.write(c_code)
128f.close()
129
130
131time_taken = (time.time() - start_time)
132
133print("Output:")
134print("\tTime taken = " + str(round(time_taken,2)) + " sec")
135print("\tbin size = " + str(round(len(sjpeg)/1024, 1)) + " KB" )
136print("\t" + OUTPUT_FILE_NAME + ".sjpg\t(bin file)" + "\n\t" + OUTPUT_FILE_NAME + ".c\t\t(c array)")
137
138print("\nAll good!")
139