未验证 提交 a17036ca 编写于 作者: Y Yegor 提交者: GitHub

fix EnginePicture.toImage; implement rawRgba toByteData; add test (#21370)

上级 4f8a6f04
......@@ -201,8 +201,8 @@ class BitmapCanvas extends EngineCanvas {
return _devicePixelRatio == EngineWindow.browserDevicePixelRatio;
}
/// Returns a data URI containing a representation of the image in this
/// canvas.
/// Returns a "data://" URI containing a representation of the image in this
/// canvas in PNG format.
String toDataUrl() {
return _canvasPool.toDataUrl();
}
......
......@@ -319,8 +319,8 @@ class _CanvasPool extends _SaveStackTracking {
}
}
// Returns a data URI containing a representation of the image in this
// canvas.
// Returns a "data://" URI containing a representation of the image in this
// canvas in PNG format.
String toDataUrl() => _canvas!.toDataUrl();
@override
......
......@@ -139,6 +139,15 @@ class HtmlImage implements ui.Image {
@override
Future<ByteData?> toByteData({ui.ImageByteFormat format = ui.ImageByteFormat.rawRgba}) {
if (format == ui.ImageByteFormat.rawRgba) {
final html.CanvasElement canvas = html.CanvasElement()
..width = width
..height = height;
final html.CanvasRenderingContext2D ctx = canvas.context2D;
ctx.drawImage(imgElement, 0, 0);
final html.ImageData imageData = ctx.getImageData(0, 0, width, height);
return Future.value(imageData.data.buffer.asByteData());
}
if (imgElement.src?.startsWith('data:') == true) {
final data = UriData.fromUri(Uri.parse(imgElement.src!));
return Future.value(data.contentAsBytes().buffer.asByteData());
......
......@@ -54,11 +54,19 @@ class EnginePicture implements ui.Picture {
..src = imageDataUrl
..width = width
..height = height;
return HtmlImage(
imageElement,
width,
height,
);
// The image loads asynchronously. We need to wait before returning,
// otherwise the returned HtmlImage will be temporarily unusable.
final Completer<ui.Image> onImageLoaded = Completer<ui.Image>.sync();
imageElement.onError.first.then(onImageLoaded.completeError);
imageElement.onLoad.first.then((_) {
onImageLoaded.complete(HtmlImage(
imageElement,
width,
height,
));
});
return onImageLoaded.future;
}
@override
......
......@@ -3,7 +3,7 @@
// found in the LICENSE file.
// @dart = 2.6
import 'dart:html' as html;
import 'dart:typed_data';
import 'package:ui/ui.dart';
import 'package:ui/src/engine.dart';
......@@ -16,40 +16,35 @@ void main() {
}
void testMain() async {
final Rect region = Rect.fromLTWH(0, 0, 500, 500);
setUp(() async {
debugShowClipLayers = true;
SurfaceSceneBuilder.debugForgetFrameScene();
for (html.Node scene in html.document.querySelectorAll('flt-scene')) {
scene.remove();
}
await webOnlyInitializePlatform();
webOnlyFontCollection.debugRegisterTestFonts();
await webOnlyFontCollection.ensureFontsLoaded();
});
test('Convert Canvas to Picture', () async {
final SurfaceSceneBuilder builder = SurfaceSceneBuilder();
final Picture testPicture = await _drawTestPictureWithCircle(region);
builder.addPicture(Offset.zero, testPicture);
html.document.body.append(builder
.build()
.webOnlyRootElement);
//await matchGoldenFile('canvas_to_picture.png', region: region, write: true);
test('Picture.toImage().toByteData()', () async {
final EnginePictureRecorder recorder = PictureRecorder();
final RecordingCanvas canvas =
recorder.beginRecording(Rect.fromLTRB(0, 0, 2, 2));
canvas.drawColor(Color(0xFFCCDD00), BlendMode.srcOver);
final Picture testPicture = recorder.endRecording();
final Image testImage = await testPicture.toImage(2, 2);
final ByteData bytes =
await testImage.toByteData(format: ImageByteFormat.rawRgba);
expect(
bytes.buffer.asUint32List(),
<int>[0xFF00DDCC, 0xFF00DDCC, 0xFF00DDCC, 0xFF00DDCC],
);
final ByteData pngBytes =
await testImage.toByteData(format: ImageByteFormat.png);
// PNG-encoding is browser-specific, but the header is standard. We only
// test the header.
final List<int> pngHeader = <int>[137, 80, 78, 71, 13, 10, 26, 10];
expect(
pngBytes.buffer.asUint8List().sublist(0, pngHeader.length),
pngHeader,
);
});
}
Picture _drawTestPictureWithCircle(Rect region) {
final EnginePictureRecorder recorder = PictureRecorder();
final RecordingCanvas canvas = recorder.beginRecording(region);
canvas.drawOval(
region,
Paint()
..style = PaintingStyle.fill
..color = Color(0xFF00FF00));
return recorder.endRecording();
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册