Я так делал.
Рисуется скрытый фрейм:
<iframe width="0" height="0" name="iframe"></iframe>
Рисуется форма ПОСЛЕ основной формы поста:
Форма для загрузки изображений с кнопкой выбора файла:
<form action="/thumbnail.php" method="post" enctype="multipart/form-data" target="iframe">
<input type="file" name="file" id="file" />
</form>
При выборке картинки срабатывает событие submit и грузит её в скрытый фрейм на /thumbnail.php.
thumbnail.php преобразовывает изображение, сохраняет на ФС, записывает кое-что в таблицу (см далее), после чего отдает путь к превью, JS из родительского окна браузера рисует блок изображения с URL этого превью.
Рисуется в основной форме поста hidden поле вида
<input type="hidden" name="thumbnail[]" value="123">
где 123 - ID картинки, которую мы положили уже на сервер и записали в таблицу вида
id | id_post | file_name | file_date
получается что-то вроде записи
123 | null | file.jpeg | 20-02-2020
при посте самой формы мы делаем update, пробегаемся по массиву thumbnail из POST и у каждой записи обновляем id_post на тот, что получили в результате сохранения поста:
update images set id_post = 1 where id = 123
крон ходит раз в 15 минут и убивает все картинки, где id_post is null и file_date < now()-1 час