File indexing completed on 2025-01-05 04:01:16
0001 /* 0002 * SPDX-FileCopyrightText: 2019-2023 Mattia Basaglia <dev@dragon.best> 0003 * 0004 * SPDX-License-Identifier: GPL-3.0-or-later 0005 */ 0006 0007 #include "spritesheet_format.hpp" 0008 #include "model/assets/composition.hpp" 0009 0010 #include <QImage> 0011 #include <QPainter> 0012 #include <QImageWriter> 0013 0014 glaxnimate::io::Autoreg<glaxnimate::io::raster::SpritesheetFormat> glaxnimate::io::raster::SpritesheetFormat::autoreg; 0015 0016 QStringList glaxnimate::io::raster::SpritesheetFormat::extensions() const 0017 { 0018 QStringList formats; 0019 formats << "png"; 0020 for ( const auto& fmt : QImageWriter::supportedImageFormats() ) 0021 if ( fmt != "jpg" && fmt != "svg" ) 0022 formats << QString::fromUtf8(fmt); 0023 return formats; 0024 } 0025 0026 std::unique_ptr<app::settings::SettingsGroup> glaxnimate::io::raster::SpritesheetFormat::save_settings(model::Composition* comp) const 0027 { 0028 int first_frame = comp->animation->first_frame.get(); 0029 int last_frame = comp->animation->last_frame.get(); 0030 int frames = last_frame - first_frame; 0031 return std::make_unique<app::settings::SettingsGroup>(app::settings::SettingList{ 0032 app::settings::Setting("frame_width", i18n("Frame Width"), i18n("Width of each frame"), comp->width.get(), 1, 999'999), 0033 app::settings::Setting("frame_height", i18n("Frame Height"), i18n("Height of each frame"), comp->height.get(), 1, 999'999), 0034 app::settings::Setting("columns", i18n("Columns"), i18n("Number of columns in the sheet"), std::ceil(math::sqrt(frames)), 1, 64), 0035 app::settings::Setting("frame_step", i18n("Time Step"), i18n("By how much each rendered frame should increase time (in frames)"), 1, 1, 16), 0036 }); 0037 } 0038 0039 bool glaxnimate::io::raster::SpritesheetFormat::on_save(QIODevice& file, const QString& filename, model::Composition* comp, const QVariantMap& setting_values) 0040 { 0041 Q_UNUSED(filename); 0042 0043 int frame_w = setting_values["frame_width"].toInt(); 0044 int frame_h = setting_values["frame_height"].toInt(); 0045 int columns = setting_values["columns"].toInt(); 0046 int frame_step = setting_values["frame_step"].toInt(); 0047 0048 if ( frame_w <= 0 || frame_h <= 0 || columns <= 0 || frame_step <= 0 ) 0049 return false; 0050 0051 int first_frame = comp->animation->first_frame.get(); 0052 int last_frame = comp->animation->last_frame.get(); 0053 int frames = (last_frame - first_frame) / frame_step; 0054 int rows = frames / columns; 0055 0056 qreal scale_x = qreal(frame_w) / comp->width.get(); 0057 qreal scale_y = qreal(frame_h) / comp->height.get(); 0058 0059 QImage bmp(frame_w * columns, frame_h * rows, QImage::Format_ARGB32); 0060 QPainter painter(&bmp); 0061 for ( int i = first_frame; i <= last_frame; i += frame_step ) 0062 { 0063 painter.save(); 0064 painter.scale(scale_x, scale_y); 0065 painter.translate((i % columns) * frame_w, (i / columns) * frame_h); 0066 painter.setClipRect(0, 0, frame_w, frame_h); 0067 comp->paint(&painter, i, model::VisualNode::Render); 0068 painter.restore(); 0069 } 0070 0071 painter.end(); 0072 0073 0074 QImageWriter writer(&file, {}); 0075 writer.setOptimizedWrite(true); 0076 if ( writer.write(bmp) ) 0077 return true; 0078 0079 error(writer.errorString()); 0080 return false; 0081 } 0082