part of dart._skwasm_impl; // Copyright 2013 The Flutter Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. class SkwasmImage extends SkwasmObjectWrapper implements ui.Image { SkwasmImage(ImageHandle handle) : super(handle, _registry) { ui.Image.onCreate?.call(this); } factory SkwasmImage.fromPixels( Uint8List pixels, int width, int height, ui.PixelFormat format, { int? rowBytes, }) { final SkDataHandle dataHandle = skDataCreate(pixels.length); final Pointer dataPointer = skDataGetPointer(dataHandle).cast(); for (int i = 0; i < pixels.length; i++) { dataPointer[i] = pixels[i]; } final ImageHandle imageHandle = imageCreateFromPixels( dataHandle, width, height, format.index, rowBytes ?? 4 * width, ); skDataDispose(dataHandle); return SkwasmImage(imageHandle); } static final SkwasmFinalizationRegistry _registry = SkwasmFinalizationRegistry(imageDispose); @override void dispose() { super.dispose(); ui.Image.onDispose?.call(this); } @override int get width => imageGetWidth(handle); @override int get height => imageGetHeight(handle); @override Future toByteData({ui.ImageByteFormat format = ui.ImageByteFormat.rawRgba}) async { if (format == ui.ImageByteFormat.png) { final ui.PictureRecorder recorder = ui.PictureRecorder(); final ui.Canvas canvas = ui.Canvas(recorder); canvas.drawImage(this, ui.Offset.zero, ui.Paint()); final DomImageBitmap bitmap = (await (renderer as SkwasmRenderer).surface.renderPictures([ recorder.endRecording() as SkwasmPicture, ])).imageBitmaps.single; final DomOffscreenCanvas offscreenCanvas = createDomOffscreenCanvas( bitmap.width.toDartInt, bitmap.height.toDartInt, ); final DomCanvasRenderingContextBitmapRenderer context = offscreenCanvas.getContext('bitmaprenderer')! as DomCanvasRenderingContextBitmapRenderer; context.transferFromImageBitmap(bitmap); final DomBlob blob = await offscreenCanvas.convertToBlob(); final JSArrayBuffer arrayBuffer = (await blob.arrayBuffer().toDart)! as JSArrayBuffer; // Zero out the contents of the canvas so that resources can be reclaimed // by the browser. context.transferFromImageBitmap(null); return ByteData.view(arrayBuffer.toDart); } else { return (renderer as SkwasmRenderer).surface.rasterizeImage(this, format); } } @override ui.ColorSpace get colorSpace => ui.ColorSpace.sRGB; @override SkwasmImage clone() { imageRef(handle); return SkwasmImage(handle); } @override bool isCloneOf(ui.Image other) => other is SkwasmImage && handle == other.handle; @override List? debugGetOpenHandleStackTraces() => null; @override String toString() => '[$width\u00D7$height]'; }