mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 05:07:34 +00:00
PixelPaint: Display an error message if exporting to PNG/BMP fails
This commit is contained in:
parent
ba807c2d44
commit
91100f2f94
3 changed files with 53 additions and 27 deletions
|
@ -55,7 +55,7 @@ Image::Image(Gfx::IntSize const& size)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void Image::paint_into(GUI::Painter& painter, Gfx::IntRect const& dest_rect)
|
void Image::paint_into(GUI::Painter& painter, Gfx::IntRect const& dest_rect) const
|
||||||
{
|
{
|
||||||
float scale = (float)dest_rect.width() / (float)rect().width();
|
float scale = (float)dest_rect.width() / (float)rect().width();
|
||||||
Gfx::PainterStateSaver saver(painter);
|
Gfx::PainterStateSaver saver(painter);
|
||||||
|
@ -188,30 +188,52 @@ Result<void, String> Image::write_to_file(const String& file_path) const
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
void Image::export_bmp(String const& file_path)
|
RefPtr<Gfx::Bitmap> Image::try_compose_bitmap() const
|
||||||
{
|
{
|
||||||
auto bitmap = Gfx::Bitmap::create(Gfx::BitmapFormat::BGRx8888, m_size);
|
auto bitmap = Gfx::Bitmap::create(Gfx::BitmapFormat::BGRx8888, m_size);
|
||||||
|
if (!bitmap)
|
||||||
|
return nullptr;
|
||||||
GUI::Painter painter(*bitmap);
|
GUI::Painter painter(*bitmap);
|
||||||
paint_into(painter, { 0, 0, m_size.width(), m_size.height() });
|
paint_into(painter, { 0, 0, m_size.width(), m_size.height() });
|
||||||
|
return bitmap;
|
||||||
Gfx::BMPWriter dumper;
|
|
||||||
auto bmp = dumper.dump(bitmap);
|
|
||||||
auto file = fopen(file_path.characters(), "wb");
|
|
||||||
fwrite(bmp.data(), sizeof(u8), bmp.size(), file);
|
|
||||||
fclose(file);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Image::export_png(String const& file_path)
|
Result<void, String> Image::export_bmp_to_file(String const& file_path)
|
||||||
{
|
{
|
||||||
auto bitmap = Gfx::Bitmap::create(Gfx::BitmapFormat::BGRA8888, m_size);
|
auto file_or_error = Core::File::open(file_path, (Core::OpenMode)(Core::OpenMode::WriteOnly | Core::OpenMode::Truncate));
|
||||||
VERIFY(bitmap);
|
if (file_or_error.is_error())
|
||||||
GUI::Painter painter(*bitmap);
|
return file_or_error.error();
|
||||||
paint_into(painter, { 0, 0, m_size.width(), m_size.height() });
|
|
||||||
|
|
||||||
auto png = Gfx::PNGWriter::encode(*bitmap);
|
auto bitmap = try_compose_bitmap();
|
||||||
auto file = fopen(file_path.characters(), "wb");
|
if (!bitmap)
|
||||||
fwrite(png.data(), sizeof(u8), png.size(), file);
|
return String { "Failed to allocate bitmap for encoding"sv };
|
||||||
fclose(file);
|
|
||||||
|
Gfx::BMPWriter dumper;
|
||||||
|
auto encoded_data = dumper.dump(bitmap);
|
||||||
|
|
||||||
|
auto& file = *file_or_error.value();
|
||||||
|
if (!file.write(encoded_data.data(), encoded_data.size()))
|
||||||
|
return String { "Failed to write encoded BMP data to file"sv };
|
||||||
|
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
Result<void, String> Image::export_png_to_file(String const& file_path)
|
||||||
|
{
|
||||||
|
auto file_or_error = Core::File::open(file_path, (Core::OpenMode)(Core::OpenMode::WriteOnly | Core::OpenMode::Truncate));
|
||||||
|
if (file_or_error.is_error())
|
||||||
|
return file_or_error.error();
|
||||||
|
|
||||||
|
auto bitmap = try_compose_bitmap();
|
||||||
|
if (!bitmap)
|
||||||
|
return String { "Failed to allocate bitmap for encoding"sv };
|
||||||
|
|
||||||
|
auto encoded_data = Gfx::PNGWriter::encode(*bitmap);
|
||||||
|
auto& file = *file_or_error.value();
|
||||||
|
if (!file.write(encoded_data.data(), encoded_data.size()))
|
||||||
|
return String { "Failed to write encoded PNG data to file"sv };
|
||||||
|
|
||||||
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
void Image::add_layer(NonnullRefPtr<Layer> layer)
|
void Image::add_layer(NonnullRefPtr<Layer> layer)
|
||||||
|
|
|
@ -41,6 +41,9 @@ public:
|
||||||
static Result<NonnullRefPtr<Image>, String> try_create_from_file(String const& file_path);
|
static Result<NonnullRefPtr<Image>, String> try_create_from_file(String const& file_path);
|
||||||
static RefPtr<Image> try_create_from_bitmap(NonnullRefPtr<Gfx::Bitmap>);
|
static RefPtr<Image> try_create_from_bitmap(NonnullRefPtr<Gfx::Bitmap>);
|
||||||
|
|
||||||
|
// This generates a new Bitmap with the final image (all layers composed according to their attributes.)
|
||||||
|
RefPtr<Gfx::Bitmap> try_compose_bitmap() const;
|
||||||
|
|
||||||
size_t layer_count() const { return m_layers.size(); }
|
size_t layer_count() const { return m_layers.size(); }
|
||||||
Layer const& layer(size_t index) const { return m_layers.at(index); }
|
Layer const& layer(size_t index) const { return m_layers.at(index); }
|
||||||
Layer& layer(size_t index) { return m_layers.at(index); }
|
Layer& layer(size_t index) { return m_layers.at(index); }
|
||||||
|
@ -52,10 +55,10 @@ public:
|
||||||
RefPtr<Image> take_snapshot() const;
|
RefPtr<Image> take_snapshot() const;
|
||||||
void restore_snapshot(Image const&);
|
void restore_snapshot(Image const&);
|
||||||
|
|
||||||
void paint_into(GUI::Painter&, Gfx::IntRect const& dest_rect);
|
void paint_into(GUI::Painter&, Gfx::IntRect const& dest_rect) const;
|
||||||
Result<void, String> write_to_file(String const& file_path) const;
|
Result<void, String> write_to_file(String const& file_path) const;
|
||||||
void export_bmp(String const& file_path);
|
Result<void, String> export_bmp_to_file(String const& file_path);
|
||||||
void export_png(String const& file_path);
|
Result<void, String> export_png_to_file(String const& file_path);
|
||||||
|
|
||||||
void move_layer_to_front(Layer&);
|
void move_layer_to_front(Layer&);
|
||||||
void move_layer_to_back(Layer&);
|
void move_layer_to_back(Layer&);
|
||||||
|
|
|
@ -138,10 +138,12 @@ int main(int argc, char** argv)
|
||||||
"As &BMP", [&](auto&) {
|
"As &BMP", [&](auto&) {
|
||||||
if (!image_editor.image())
|
if (!image_editor.image())
|
||||||
return;
|
return;
|
||||||
Optional<String> save_path = GUI::FilePicker::get_save_filepath(window, "untitled", "bmp");
|
auto save_path = GUI::FilePicker::get_save_filepath(window, "untitled", "bmp");
|
||||||
if (!save_path.has_value())
|
if (!save_path.has_value())
|
||||||
return;
|
return;
|
||||||
image_editor.image()->export_bmp(save_path.value());
|
auto result = image_editor.image()->export_bmp_to_file(save_path.value());
|
||||||
|
if (result.is_error())
|
||||||
|
GUI::MessageBox::show_error(window, String::formatted("Export to BMP failed: {}", result.error()));
|
||||||
},
|
},
|
||||||
window));
|
window));
|
||||||
export_submenu.add_action(
|
export_submenu.add_action(
|
||||||
|
@ -149,13 +151,12 @@ int main(int argc, char** argv)
|
||||||
"As &PNG", [&](auto&) {
|
"As &PNG", [&](auto&) {
|
||||||
if (!image_editor.image())
|
if (!image_editor.image())
|
||||||
return;
|
return;
|
||||||
|
auto save_path = GUI::FilePicker::get_save_filepath(window, "untitled", "png");
|
||||||
Optional<String> save_path = GUI::FilePicker::get_save_filepath(window, "untitled", "png");
|
|
||||||
|
|
||||||
if (!save_path.has_value())
|
if (!save_path.has_value())
|
||||||
return;
|
return;
|
||||||
|
auto result = image_editor.image()->export_bmp_to_file(save_path.value());
|
||||||
image_editor.image()->export_png(save_path.value());
|
if (result.is_error())
|
||||||
|
GUI::MessageBox::show_error(window, String::formatted("Export to PNG failed: {}", result.error()));
|
||||||
},
|
},
|
||||||
window));
|
window));
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue