Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 38 additions & 47 deletions lib/ui/painting/image_encoding.cc
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,6 @@ class Context;
namespace flutter {
namespace {

// This must be kept in sync with the enum in painting.dart
enum ImageByteFormat {
kRawRGBA,
kRawStraightRGBA,
kRawUnmodified,
kRawExtendedRgba128,
kPNG,
};

void FinalizeSkData(void* isolate_callback_data, void* peer) {
SkData* buffer = reinterpret_cast<SkData*>(peer);
buffer->unref();
Expand Down Expand Up @@ -107,44 +98,6 @@ sk_sp<SkData> CopyImageByteData(const sk_sp<SkImage>& raster_image,
return SkData::MakeWithCopy(pixmap.addr(), pixmap.computeByteSize());
}

sk_sp<SkData> EncodeImage(const sk_sp<SkImage>& raster_image,
ImageByteFormat format) {
TRACE_EVENT0("flutter", __FUNCTION__);

if (!raster_image) {
return nullptr;
}

switch (format) {
case kPNG: {
auto png_image = SkPngEncoder::Encode(nullptr, raster_image.get(), {});

if (png_image == nullptr) {
FML_LOG(ERROR) << "Could not convert raster image to PNG.";
return nullptr;
};
return png_image;
}
case kRawRGBA:
return CopyImageByteData(raster_image, kRGBA_8888_SkColorType,
kPremul_SkAlphaType);

case kRawStraightRGBA:
return CopyImageByteData(raster_image, kRGBA_8888_SkColorType,
kUnpremul_SkAlphaType);

case kRawUnmodified:
return CopyImageByteData(raster_image, raster_image->colorType(),
raster_image->alphaType());
case kRawExtendedRgba128:
return CopyImageByteData(raster_image, kRGBA_F32_SkColorType,
kUnpremul_SkAlphaType);
}

FML_LOG(ERROR) << "Unknown error encoding image.";
return nullptr;
}

void EncodeImageAndInvokeDataCallback(
const sk_sp<DlImage>& image,
std::unique_ptr<DartPersistentValue> callback,
Expand Down Expand Up @@ -229,4 +182,42 @@ Dart_Handle EncodeImage(CanvasImage* canvas_image,
return Dart_Null();
}

sk_sp<SkData> EncodeImage(const sk_sp<SkImage>& raster_image,
ImageByteFormat format) {
TRACE_EVENT0("flutter", __FUNCTION__);

if (!raster_image) {
return nullptr;
}

switch (format) {
case kPNG: {
auto png_image = SkPngEncoder::Encode(nullptr, raster_image.get(), {});

if (png_image == nullptr) {
FML_LOG(ERROR) << "Could not convert raster image to PNG.";
return nullptr;
};
return png_image;
}
case kRawRGBA:
return CopyImageByteData(raster_image, kRGBA_8888_SkColorType,
kPremul_SkAlphaType);

case kRawStraightRGBA:
return CopyImageByteData(raster_image, kRGBA_8888_SkColorType,
kUnpremul_SkAlphaType);

case kRawUnmodified:
return CopyImageByteData(raster_image, raster_image->colorType(),
raster_image->alphaType());
case kRawExtendedRgba128:
return CopyImageByteData(raster_image, kRGBA_F32_SkColorType,
kUnpremul_SkAlphaType);
}

FML_LOG(ERROR) << "Unknown error encoding image.";
return nullptr;
}

} // namespace flutter
13 changes: 13 additions & 0 deletions lib/ui/painting/image_encoding.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,29 @@
#ifndef FLUTTER_LIB_UI_PAINTING_IMAGE_ENCODING_H_
#define FLUTTER_LIB_UI_PAINTING_IMAGE_ENCODING_H_

#include "third_party/skia/include/core/SkImage.h"
#include "third_party/tonic/dart_library_natives.h"

namespace flutter {

class CanvasImage;

// This must be kept in sync with the enum in painting.dart
enum ImageByteFormat {
kRawRGBA,
kRawStraightRGBA,
kRawUnmodified,
kRawExtendedRgba128,
kPNG,
};

Dart_Handle EncodeImage(CanvasImage* canvas_image,
int format,
Dart_Handle callback_handle);

sk_sp<SkData> EncodeImage(const sk_sp<SkImage>& raster_image,
ImageByteFormat format);

} // namespace flutter

#endif // FLUTTER_LIB_UI_PAINTING_IMAGE_ENCODING_H_
23 changes: 23 additions & 0 deletions lib/ui/painting/image_encoding_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,29 @@ TEST(ImageEncodingImpellerTest, ConvertDlImageToSkImage10XR) {
context);
EXPECT_TRUE(did_call);
}

TEST(ImageEncodingImpellerTest, PngEncoding10XR) {
int width = 100;
int height = 100;
SkImageInfo info = SkImageInfo::Make(
width, height, kBGR_101010x_XR_SkColorType, kUnpremul_SkAlphaType);

auto surface = SkSurfaces::Raster(info);
SkCanvas* canvas = surface->getCanvas();

SkPaint paint;
paint.setColor(SK_ColorBLUE);
paint.setAntiAlias(true);

canvas->clear(SK_ColorWHITE);
canvas->drawCircle(width / 2, height / 2, 100, paint);

sk_sp<SkImage> image = surface->makeImageSnapshot();

sk_sp<SkData> png = EncodeImage(image, ImageByteFormat::kPNG);
EXPECT_TRUE(png);
}

#endif // IMPELLER_SUPPORTS_RENDERING

} // namespace testing
Expand Down