mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 01:17:34 +00:00
PixelPaint: Guess image type based on its filename
We do this in ImageViewer so it understands TGA images; let's do it in PixelPaint as well :^)
This commit is contained in:
parent
e272f796ad
commit
1c19c2bc92
5 changed files with 13 additions and 9 deletions
|
@ -50,13 +50,14 @@ void Image::paint_into(GUI::Painter& painter, Gfx::IntRect const& dest_rect, flo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorOr<NonnullRefPtr<Gfx::Bitmap>> Image::decode_bitmap(ReadonlyBytes bitmap_data)
|
ErrorOr<NonnullRefPtr<Gfx::Bitmap>> Image::decode_bitmap(ReadonlyBytes bitmap_data, Optional<StringView> guessed_mime_type)
|
||||||
{
|
{
|
||||||
// Spawn a new ImageDecoder service process and connect to it.
|
// Spawn a new ImageDecoder service process and connect to it.
|
||||||
auto client = TRY(ImageDecoderClient::Client::try_create());
|
auto client = TRY(ImageDecoderClient::Client::try_create());
|
||||||
|
auto optional_mime_type = guessed_mime_type.map([](auto mime_type) { return mime_type.to_deprecated_string(); });
|
||||||
|
|
||||||
// FIXME: Find a way to avoid the memory copying here.
|
// FIXME: Find a way to avoid the memory copying here.
|
||||||
auto maybe_decoded_image = client->decode_image(bitmap_data);
|
auto maybe_decoded_image = client->decode_image(bitmap_data, optional_mime_type);
|
||||||
if (!maybe_decoded_image.has_value())
|
if (!maybe_decoded_image.has_value())
|
||||||
return Error::from_string_literal("Image decode failed");
|
return Error::from_string_literal("Image decode failed");
|
||||||
|
|
||||||
|
@ -91,13 +92,13 @@ ErrorOr<NonnullRefPtr<Image>> Image::create_from_pixel_paint_json(JsonObject con
|
||||||
|
|
||||||
auto bitmap_base64_encoded = layer_object.get_deprecated_string("bitmap"sv).value();
|
auto bitmap_base64_encoded = layer_object.get_deprecated_string("bitmap"sv).value();
|
||||||
auto bitmap_data = TRY(decode_base64(bitmap_base64_encoded));
|
auto bitmap_data = TRY(decode_base64(bitmap_base64_encoded));
|
||||||
auto bitmap = TRY(decode_bitmap(bitmap_data));
|
auto bitmap = TRY(decode_bitmap(bitmap_data, {}));
|
||||||
auto layer = TRY(Layer::create_with_bitmap(*image, move(bitmap), name));
|
auto layer = TRY(Layer::create_with_bitmap(*image, move(bitmap), name));
|
||||||
|
|
||||||
if (auto const& mask_object = layer_object.get_deprecated_string("mask"sv); mask_object.has_value()) {
|
if (auto const& mask_object = layer_object.get_deprecated_string("mask"sv); mask_object.has_value()) {
|
||||||
auto mask_base64_encoded = mask_object.value();
|
auto mask_base64_encoded = mask_object.value();
|
||||||
auto mask_data = TRY(decode_base64(mask_base64_encoded));
|
auto mask_data = TRY(decode_base64(mask_base64_encoded));
|
||||||
auto mask = TRY(decode_bitmap(mask_data));
|
auto mask = TRY(decode_bitmap(mask_data, {}));
|
||||||
TRY(layer->set_bitmaps(layer->content_bitmap(), mask));
|
TRY(layer->set_bitmaps(layer->content_bitmap(), mask));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include "Selection.h"
|
#include "Selection.h"
|
||||||
#include <AK/HashTable.h>
|
#include <AK/HashTable.h>
|
||||||
#include <AK/JsonObjectSerializer.h>
|
#include <AK/JsonObjectSerializer.h>
|
||||||
|
#include <AK/Optional.h>
|
||||||
#include <AK/RefCounted.h>
|
#include <AK/RefCounted.h>
|
||||||
#include <AK/RefPtr.h>
|
#include <AK/RefPtr.h>
|
||||||
#include <AK/Result.h>
|
#include <AK/Result.h>
|
||||||
|
@ -48,7 +49,7 @@ public:
|
||||||
static ErrorOr<NonnullRefPtr<Image>> create_from_pixel_paint_json(JsonObject const&);
|
static ErrorOr<NonnullRefPtr<Image>> create_from_pixel_paint_json(JsonObject const&);
|
||||||
static ErrorOr<NonnullRefPtr<Image>> create_from_bitmap(NonnullRefPtr<Gfx::Bitmap> const&);
|
static ErrorOr<NonnullRefPtr<Image>> create_from_bitmap(NonnullRefPtr<Gfx::Bitmap> const&);
|
||||||
|
|
||||||
static ErrorOr<NonnullRefPtr<Gfx::Bitmap>> decode_bitmap(ReadonlyBytes);
|
static ErrorOr<NonnullRefPtr<Gfx::Bitmap>> decode_bitmap(ReadonlyBytes, Optional<StringView> guessed_mime_type);
|
||||||
|
|
||||||
// This generates a new Bitmap with the final image (all layers composed according to their attributes.)
|
// This generates a new Bitmap with the final image (all layers composed according to their attributes.)
|
||||||
ErrorOr<NonnullRefPtr<Gfx::Bitmap>> compose_bitmap(Gfx::BitmapFormat format) const;
|
ErrorOr<NonnullRefPtr<Gfx::Bitmap>> compose_bitmap(Gfx::BitmapFormat format) const;
|
||||||
|
|
|
@ -1288,7 +1288,7 @@ void MainWidget::set_mask_actions_for_layer(Layer* layer)
|
||||||
|
|
||||||
void MainWidget::open_image(FileSystemAccessClient::File file)
|
void MainWidget::open_image(FileSystemAccessClient::File file)
|
||||||
{
|
{
|
||||||
auto try_load = m_loader.load_from_file(file.release_stream());
|
auto try_load = m_loader.load_from_file(file.filename(), file.release_stream());
|
||||||
if (try_load.is_error()) {
|
if (try_load.is_error()) {
|
||||||
GUI::MessageBox::show_error(window(), MUST(String::formatted("Unable to open file: {}, {}", file.filename(), try_load.release_error())));
|
GUI::MessageBox::show_error(window(), MUST(String::formatted("Unable to open file: {}, {}", file.filename(), try_load.release_error())));
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -8,20 +8,22 @@
|
||||||
#include "Image.h"
|
#include "Image.h"
|
||||||
#include "Layer.h"
|
#include "Layer.h"
|
||||||
#include <AK/JsonObject.h>
|
#include <AK/JsonObject.h>
|
||||||
|
#include <LibCore/MimeData.h>
|
||||||
#include <LibImageDecoderClient/Client.h>
|
#include <LibImageDecoderClient/Client.h>
|
||||||
|
|
||||||
namespace PixelPaint {
|
namespace PixelPaint {
|
||||||
|
|
||||||
ErrorOr<void> ProjectLoader::load_from_file(NonnullOwnPtr<Core::File> file)
|
ErrorOr<void> ProjectLoader::load_from_file(StringView filename, NonnullOwnPtr<Core::File> file)
|
||||||
{
|
{
|
||||||
auto contents = TRY(file->read_until_eof());
|
auto contents = TRY(file->read_until_eof());
|
||||||
|
|
||||||
auto json_or_error = JsonValue::from_string(contents);
|
auto json_or_error = JsonValue::from_string(contents);
|
||||||
if (json_or_error.is_error()) {
|
if (json_or_error.is_error()) {
|
||||||
m_is_raw_image = true;
|
m_is_raw_image = true;
|
||||||
|
auto guessed_mime_type = Core::guess_mime_type_based_on_filename(filename);
|
||||||
|
|
||||||
// FIXME: Find a way to avoid the memory copy here.
|
// FIXME: Find a way to avoid the memory copy here.
|
||||||
auto bitmap = TRY(Image::decode_bitmap(contents));
|
auto bitmap = TRY(Image::decode_bitmap(contents, guessed_mime_type));
|
||||||
auto image = TRY(Image::create_from_bitmap(move(bitmap)));
|
auto image = TRY(Image::create_from_bitmap(move(bitmap)));
|
||||||
|
|
||||||
m_image = image;
|
m_image = image;
|
||||||
|
|
|
@ -18,7 +18,7 @@ public:
|
||||||
ProjectLoader() = default;
|
ProjectLoader() = default;
|
||||||
~ProjectLoader() = default;
|
~ProjectLoader() = default;
|
||||||
|
|
||||||
ErrorOr<void> load_from_file(NonnullOwnPtr<Core::File>);
|
ErrorOr<void> load_from_file(StringView filename, NonnullOwnPtr<Core::File>);
|
||||||
|
|
||||||
bool is_raw_image() const { return m_is_raw_image; }
|
bool is_raw_image() const { return m_is_raw_image; }
|
||||||
RefPtr<Image> release_image() const { return move(m_image); }
|
RefPtr<Image> release_image() const { return move(m_image); }
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue