Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Add createImageFromTextureSource method to ui_web #53483

Merged
merged 11 commits into from
Jun 21, 2024
23 changes: 23 additions & 0 deletions lib/web_ui/lib/src/engine/canvaskit/renderer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,29 @@ class CanvasKitRenderer implements Renderer {
return CkImage(skImage);
}

@override
FutureOr<ui.Image> createImageFromTextureSource(Object object,
{required int width, required int height, required bool transferOwnership}) async {
if(!transferOwnership) {
final DomImageBitmap bitmap = await createImageBitmap(object.toJSAnyShallow, (x:0, y: 0, width: width, height: height));
return createImageFromImageBitmap(bitmap);
}
final SkImage? skImage = canvasKit.MakeLazyImageFromTextureSourceWithInfo(
object,
SkPartialImageInfo(
width: width.toDouble(),
height: height.toDouble(),
alphaType: canvasKit.AlphaType.Premul,
colorType: canvasKit.ColorType.RGBA_8888,
colorSpace: SkColorSpaceSRGB,
));

if (skImage == null) {
throw Exception('Failed to convert image bitmap to an SkImage.');
}
return CkImage(skImage);
}

@override
void decodeImageFromPixels(Uint8List pixels, int width, int height,
ui.PixelFormat format, ui.ImageDecoderCallback callback,
Expand Down
5 changes: 5 additions & 0 deletions lib/web_ui/lib/src/engine/html/renderer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -371,4 +371,9 @@ class HtmlRenderer implements Renderer {
imageElement.src = await canvas.toDataUrl();
return completer.future;
}

@override
FutureOr<ui.Image> createImageFromTextureSource(Object object, { required int width, required int height, required bool transferOwnership }) {
throw Exception('Not implemented for HTML renderer');
}
}
43 changes: 21 additions & 22 deletions lib/web_ui/lib/src/engine/renderer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -103,17 +103,18 @@ abstract class Renderer {
Float32List? matrix4,
]);

ui.ImageFilter createBlurImageFilter({
double sigmaX = 0.0,
double sigmaY = 0.0,
ui.TileMode tileMode = ui.TileMode.clamp});
ui.ImageFilter createDilateImageFilter({ double radiusX = 0.0, double radiusY = 0.0});
ui.ImageFilter createErodeImageFilter({ double radiusX = 0.0, double radiusY = 0.0});
ui.ImageFilter createMatrixImageFilter(
Float64List matrix4, {
ui.FilterQuality filterQuality = ui.FilterQuality.low
});
ui.ImageFilter composeImageFilters({required ui.ImageFilter outer, required ui.ImageFilter inner});
ui.ImageFilter createBlurImageFilter(
{double sigmaX = 0.0,
double sigmaY = 0.0,
ui.TileMode tileMode = ui.TileMode.clamp});
ui.ImageFilter createDilateImageFilter(
{double radiusX = 0.0, double radiusY = 0.0});
ui.ImageFilter createErodeImageFilter(
{double radiusX = 0.0, double radiusY = 0.0});
ui.ImageFilter createMatrixImageFilter(Float64List matrix4,
{ui.FilterQuality filterQuality = ui.FilterQuality.low});
ui.ImageFilter composeImageFilters(
{required ui.ImageFilter outer, required ui.ImageFilter inner});

Future<ui.Codec> instantiateImageCodec(
Uint8List list, {
Expand All @@ -129,17 +130,15 @@ abstract class Renderer {

FutureOr<ui.Image> createImageFromImageBitmap(DomImageBitmap imageSource);

void decodeImageFromPixels(
Uint8List pixels,
int width,
int height,
ui.PixelFormat format,
ui.ImageDecoderCallback callback, {
int? rowBytes,
int? targetWidth,
int? targetHeight,
bool allowUpscaling = true
});
FutureOr<ui.Image> createImageFromTextureSource(Object object,
{required int width, required int height, required bool transferOwnership });

void decodeImageFromPixels(Uint8List pixels, int width, int height,
ui.PixelFormat format, ui.ImageDecoderCallback callback,
{int? rowBytes,
int? targetWidth,
int? targetHeight,
bool allowUpscaling = true});

ui.ImageShader createImageShader(
ui.Image image,
Expand Down
13 changes: 13 additions & 0 deletions lib/web_ui/lib/src/engine/skwasm/skwasm_impl/renderer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -472,6 +472,19 @@ class SkwasmRenderer implements Renderer {
surface.handle,
));
}

@override
FutureOr<ui.Image> createImageFromTextureSource(Object textureSource, { required int width, required int height, required bool transferOwnership }) async {
if(!transferOwnership) {
textureSource = await createImageBitmap(textureSource.toJSAnyShallow, (x: 0, y: 0, width: width, height: height));
}
return SkwasmImage(imageCreateFromTextureSource(
textureSource as JSObject,
width,
height,
surface.handle,
));
}
}

class SkwasmPictureRenderer implements PictureRenderer {
Expand Down
5 changes: 5 additions & 0 deletions lib/web_ui/lib/src/engine/skwasm/skwasm_stub/renderer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -189,4 +189,9 @@ class SkwasmRenderer implements Renderer {
ui.Image createImageFromImageBitmap(DomImageBitmap imageSource) {
throw UnimplementedError('Skwasm not implemented on this platform.');
}

@override
ui.Image createImageFromTextureSource(Object object, { required int width, required int height, required bool transferOwnership }) {
throw Exception('Skwasm not implemented on this platform.');
}
}
14 changes: 14 additions & 0 deletions lib/web_ui/lib/ui_web/src/ui_web/images.dart
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,17 @@ FutureOr<ui.Image> createImageFromImageBitmap(JSAny imageSource) {
imageSource as DomImageBitmap,
);
}

/// Creates a [ui.Image] from a valid texture source (for example
/// HTMLImageElement | HTMLVideoElement | HTMLCanvasElement).
///
/// By default, [transferOwnership] specifies that the ownership of the texture
/// will be not be transferred to the renderer, and a copy of the texture source
/// will be made. If this is not desired, the ownership of the object can be
/// transferred to the renderer and the engine will take ownership of the
/// texture source and consume its contents.
FutureOr<ui.Image> createImageFromTextureSource(Object object, { required int width, required int height, bool transferOwnership = false }) {
return renderer.createImageFromTextureSource(
object, width: width, height: height, transferOwnership: transferOwnership
);
}
Loading