blob: 85ae0715d8ff5f70b55dc00df87104038e93ed2b [file] [log] [blame]
Richard Burtonf32a86a2022-11-15 11:46:11 +00001# SPDX-FileCopyrightText: Copyright 2021 Arm Limited and/or its affiliates <open-source-office@arm.com>
alexander3c798932021-03-26 21:42:19 +00002# SPDX-License-Identifier: Apache-2.0
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15
16"""
17Utility script to convert a set of RGB images in a given location into
18corresponding cpp files and a single hpp file referencing the vectors
19from the cpp files.
20"""
21import datetime
22import glob
23import math
Richard Burton17069622022-03-17 10:54:26 +000024from pathlib import Path
alexander3c798932021-03-26 21:42:19 +000025from argparse import ArgumentParser
Richard Burton17069622022-03-17 10:54:26 +000026
27import numpy as np
alexander3c798932021-03-26 21:42:19 +000028from PIL import Image, UnidentifiedImageError
29from jinja2 import Environment, FileSystemLoader
30
31parser = ArgumentParser()
32parser.add_argument("--image_path", type=str, help="path to images folder or image file to convert.")
33parser.add_argument("--source_folder_path", type=str, help="path to source folder to be generated.")
34parser.add_argument("--header_folder_path", type=str, help="path to header folder to be generated.")
35parser.add_argument("--image_size", type=int, nargs=2, help="Size (width and height) of the converted images.")
36parser.add_argument("--license_template", type=str, help="Header template file",
37 default="header_template.txt")
38args = parser.parse_args()
39
Richard Burton17069622022-03-17 10:54:26 +000040env = Environment(loader=FileSystemLoader(Path(__file__).parent / 'templates'),
alexander3c798932021-03-26 21:42:19 +000041 trim_blocks=True,
42 lstrip_blocks=True)
43
44
45def write_hpp_file(header_file_path, cc_file_path, header_template_file, num_images, image_filenames,
46 image_array_names, image_size):
47 print(f"++ Generating {header_file_path}")
48 header_template = env.get_template(header_template_file)
Richard Burton17069622022-03-17 10:54:26 +000049 hdr = header_template.render(script_name=Path(__file__).name,
alexander3c798932021-03-26 21:42:19 +000050 gen_time=datetime.datetime.now(),
51 year=datetime.datetime.now().year)
52 env.get_template('Images.hpp.template').stream(common_template_header=hdr,
53 imgs_count=num_images,
54 img_size=str(image_size[0] * image_size[1] * 3),
55 var_names=image_array_names) \
56 .dump(str(header_file_path))
57
58 env.get_template('Images.cc.template').stream(common_template_header=hdr,
59 var_names=image_array_names,
60 img_names=image_filenames) \
61 .dump(str(cc_file_path))
62
63
64def write_individual_img_cc_file(image_filename, cc_filename, header_template_file, original_image,
65 image_size, array_name):
Richard Burton17069622022-03-17 10:54:26 +000066 print(f"++ Converting {image_filename} to {cc_filename.name}")
alexander3c798932021-03-26 21:42:19 +000067
68 header_template = env.get_template(header_template_file)
Richard Burton17069622022-03-17 10:54:26 +000069 hdr = header_template.render(script_name=Path(__file__).name,
alexander3c798932021-03-26 21:42:19 +000070 gen_time=datetime.datetime.now(),
Richard Burton17069622022-03-17 10:54:26 +000071 file_name=image_filename,
alexander3c798932021-03-26 21:42:19 +000072 year=datetime.datetime.now().year)
Isabella Gottardi79d41542021-10-20 15:52:32 +010073 # IFM size
74 ifm_width = image_size[0]
75 ifm_height = image_size[1]
alexander3c798932021-03-26 21:42:19 +000076
Isabella Gottardi79d41542021-10-20 15:52:32 +010077 # Aspect ratio resize
78 scale_ratio = (float)(max(ifm_width, ifm_height)) / (float)(min(original_image.size[0], original_image.size[1]))
79 resized_width = (int)(original_image.size[0] * scale_ratio)
80 resized_height = (int)(original_image.size[1] * scale_ratio)
81 resized_image = original_image.resize([resized_width,resized_height], Image.BILINEAR)
82
83 # Crop the center of the image
84 resized_image = resized_image.crop((
85 (resized_width - ifm_width) / 2, # left
86 (resized_height - ifm_height) / 2, # top
87 (resized_width + ifm_width) / 2, # right
88 (resized_height + ifm_height) / 2 # bottom
89 ))
alexander3c798932021-03-26 21:42:19 +000090
91 # Convert the image and write it to the cc file
92 rgb_data = np.array(resized_image, dtype=np.uint8).flatten()
93 hex_line_generator = (', '.join(map(hex, sub_arr))
94 for sub_arr in np.array_split(rgb_data, math.ceil(len(rgb_data) / 20)))
95 env.get_template('image.cc.template').stream(common_template_header=hdr,
96 var_name=array_name,
97 img_data=hex_line_generator) \
98 .dump(str(cc_filename))
99
100
101def main(args):
102 # Keep the count of the images converted
103 image_idx = 0
104 image_filenames = []
105 image_array_names = []
106
Richard Burton17069622022-03-17 10:54:26 +0000107 if Path(args.image_path).is_dir():
108 filepaths = sorted(glob.glob(str(Path(args.image_path) / '**/*.*'), recursive=True))
109 elif Path(args.image_path).is_file():
alexander3c798932021-03-26 21:42:19 +0000110 filepaths = [args.image_path]
111 else:
112 raise OSError("Directory or file does not exist.")
113
114 for filepath in filepaths:
Richard Burton17069622022-03-17 10:54:26 +0000115 filename = Path(filepath).name
alexander3c798932021-03-26 21:42:19 +0000116
117 try:
118 original_image = Image.open(filepath).convert("RGB")
119 except UnidentifiedImageError:
120 print(f"-- Skipping file {filepath} due to unsupported image format.")
121 continue
122
123 image_filenames.append(filename)
124
125 # Save the cc file
Richard Burton17069622022-03-17 10:54:26 +0000126 cc_filename = Path(args.source_folder_path) / (Path(filename).stem.replace(" ", "_") + ".cc")
alexander3c798932021-03-26 21:42:19 +0000127 array_name = "im" + str(image_idx)
128 image_array_names.append(array_name)
129 write_individual_img_cc_file(filename, cc_filename, args.license_template,
130 original_image, args.image_size, array_name)
131
132 # Increment image index
133 image_idx = image_idx + 1
134
135 header_filename = "InputFiles.hpp"
Richard Burton17069622022-03-17 10:54:26 +0000136 header_filepath = Path(args.header_folder_path) / header_filename
alexander3c798932021-03-26 21:42:19 +0000137 common_cc_filename = "InputFiles.cc"
Richard Burton17069622022-03-17 10:54:26 +0000138 common_cc_filepath = Path(args.source_folder_path) / common_cc_filename
Kshitij Sisodia659fcd92021-05-19 10:30:06 +0100139
140 if len(image_filenames) > 0:
141 write_hpp_file(header_filepath, common_cc_filepath, args.license_template,
142 image_idx, image_filenames, image_array_names, args.image_size)
143 else:
144 raise FileNotFoundError("No valid images found.")
alexander3c798932021-03-26 21:42:19 +0000145
146
147if __name__ == '__main__':
148 main(args)