mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-07-31 07:22:03 +08:00
CLI thumbnails - use thumbnail from 3MF
This commit is contained in:
parent
4dabb5ade5
commit
cd81c686d1
@ -58,6 +58,8 @@
|
||||
#include "libslic3r/Format/STL.hpp"
|
||||
#include "libslic3r/Format/OBJ.hpp"
|
||||
#include "libslic3r/Format/SL1.hpp"
|
||||
#include "libslic3r/miniz_extension.hpp"
|
||||
#include "libslic3r/PNGReadWrite.hpp"
|
||||
#include "libslic3r/Utils.hpp"
|
||||
#include "libslic3r/Thread.hpp"
|
||||
#include "libslic3r/BlacklistedLibraryCheck.hpp"
|
||||
@ -671,8 +673,67 @@ int CLI::run(int argc, char **argv)
|
||||
std::string outfile_final;
|
||||
print->process();
|
||||
if (printer_technology == ptFFF) {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
std::function<ThumbnailsList(const ThumbnailsParams&)> thumbnail_generator_cli;
|
||||
if (!fff_print.model().objects.empty() && boost::iends_with(fff_print.model().objects.front()->input_file, ".3mf")) {
|
||||
std::string filename = fff_print.model().objects.front()->input_file;
|
||||
thumbnail_generator_cli = [filename](const ThumbnailsParams&) {
|
||||
ThumbnailsList list_out;
|
||||
|
||||
mz_zip_archive archive;
|
||||
mz_zip_zero_struct(&archive);
|
||||
|
||||
if (!open_zip_reader(&archive, filename))
|
||||
return list_out;
|
||||
mz_uint num_entries = mz_zip_reader_get_num_files(&archive);
|
||||
mz_zip_archive_file_stat stat;
|
||||
|
||||
int index = mz_zip_reader_locate_file(&archive, "Metadata/thumbnail.png", nullptr, 0);
|
||||
if (index < 0 || !mz_zip_reader_file_stat(&archive, index, &stat))
|
||||
return list_out;
|
||||
std::string buffer;
|
||||
buffer.resize(int(stat.m_uncomp_size));
|
||||
mz_bool res = mz_zip_reader_extract_file_to_mem(&archive, stat.m_filename, buffer.data(), (size_t)stat.m_uncomp_size, 0);
|
||||
if (res == 0)
|
||||
return list_out;
|
||||
close_zip_reader(&archive);
|
||||
|
||||
std::vector<unsigned char> data;
|
||||
unsigned width = 0;
|
||||
unsigned height = 0;
|
||||
png::decode_png(buffer, data, width, height);
|
||||
|
||||
{
|
||||
// Flip the image vertically so it matches the convention in Thumbnails generator.
|
||||
const int row_size = width * 4; // Each pixel is 4 bytes (RGBA)
|
||||
std::vector<unsigned char> temp_row(row_size);
|
||||
for (int i = 0; i < height / 2; ++i) {
|
||||
unsigned char* top_row = &data[i * row_size];
|
||||
unsigned char* bottom_row = &data[(height - i - 1) * row_size];
|
||||
std::copy(bottom_row, bottom_row + row_size, temp_row.begin());
|
||||
std::copy(top_row, top_row + row_size, bottom_row);
|
||||
std::copy(temp_row.begin(), temp_row.end(), top_row);
|
||||
}
|
||||
}
|
||||
|
||||
ThumbnailData th;
|
||||
th.set(width, height);
|
||||
th.pixels = data;
|
||||
list_out.push_back(th);
|
||||
return list_out;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// The outfile is processed by a PlaceholderParser.
|
||||
outfile = fff_print.export_gcode(outfile, nullptr, nullptr);
|
||||
outfile = fff_print.export_gcode(outfile, nullptr, thumbnail_generator_cli);
|
||||
outfile_final = fff_print.print_statistics().finalize_output_path(outfile);
|
||||
} else {
|
||||
outfile = sla_print.output_filepath(outfile);
|
||||
|
@ -190,6 +190,34 @@ fopen_failed:
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
bool decode_png(const std::string& png_data, std::vector<unsigned char>& image_data, unsigned& width, unsigned& height)
|
||||
{
|
||||
png_image image;
|
||||
memset(&image, 0, sizeof(image));
|
||||
image.version = PNG_IMAGE_VERSION;
|
||||
|
||||
if (!png_image_begin_read_from_memory(&image, png_data.data(), png_data.size()))
|
||||
return false;
|
||||
|
||||
image.format = PNG_FORMAT_RGBA;
|
||||
|
||||
// Allocate memory for the image data
|
||||
image_data.resize(PNG_IMAGE_SIZE(image));
|
||||
if (!png_image_finish_read(&image, nullptr, image_data.data(), 0, nullptr)) {
|
||||
png_image_free(&image);
|
||||
return false;
|
||||
}
|
||||
|
||||
width = image.width;
|
||||
height = image.height;
|
||||
|
||||
png_image_free(&image);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool write_rgb_to_file(const char *file_name_utf8, size_t width, size_t height, const uint8_t *data_rgb)
|
||||
{
|
||||
return write_rgb_or_gray_to_file(file_name_utf8, width, height, PNG_COLOR_TYPE_RGB, data_rgb);
|
||||
|
@ -74,7 +74,7 @@ template<class Img> bool decode_png(const ReadBuf &in_buf, Img &out_img)
|
||||
|
||||
// TODO: std::istream of FILE* could be similarly adapted in case its needed...
|
||||
|
||||
|
||||
bool decode_png(const std::string& png_data, std::vector<unsigned char>& image_data, unsigned& width, unsigned& height);
|
||||
|
||||
// Down to earth function to store a packed RGB image to file. Mostly useful for debugging purposes.
|
||||
bool write_rgb_to_file(const char *file_name_utf8, size_t width, size_t height, const uint8_t *data_rgb);
|
||||
|
Loading…
x
Reference in New Issue
Block a user