在 Flutter 中,我創建了一個簡單的繪圖應用程式,它支持 android、iOS 和 web。它將從 url 加載影像作為背景,用戶將能夠在其上繪制線條并添加文本。問題出在網路上,特別是在基于 chrome 的瀏覽器中,缺少背景,盡管它在 Safari 和 Firefox 中就像一個魅力。
首先,我有來自網路的圖片網址,我將其轉換為dart:ui
圖片
Future<ui.Image?> loadUiNetworkImage(String? url) async {
if (url == null) return null;
final http.Response response = await http.get(Uri.parse(url));
final list = response.bodyBytes;
final completer = Completer<ui.Image>();
ui.decodeImageFromList(list, completer.complete);
return completer.future;
}
final background = await loadUiNetworkImage(backgroundUrl);
然后在我的 CustomPainter 小部件中,我使用paintImage
函式將影像作為背景:
@override
void paint(Canvas canvas, Size size) {
_addBackground(ui.Image background, {double scale = 1.0}) {
final width = background.width * scale;
final height = background.height * scale;
final left = (size.width - width) / 2.0;
final top = (size.height - height) / 2.0;
paintImage(
canvas: canvas,
rect: Rect.fromLTWH(left, top, width, height),
image: background,
fit: BoxFit.scaleDown,
repeat: ImageRepeat.noRepeat,
scale: 1.0,
alignment: Alignment.center,
flipHorizontally: false,
filterQuality: FilterQuality.high
);
}
if (background != null) {
final scale = min(size.width / background!.width, size.height / background!.height);
_addBackground(background!, scale: scale);
canvas.saveLayer(null, Paint());
}
// also some drawings i.e. `drawLine` & `TextPainter`
}
這是我的 CustomPainter 駐留在小部件樹中:
RepaintBoundary(
key: _globalKey,
child: Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
color: Colors.white,
child: StreamBuilder<List<dynamic>>(
stream: linesStreamController.stream,
builder: (context, snapshot) {
return CustomPaint(
painter: Sketcher(
background: _background,
prevDrawing: _prevDrawing,
lines: _lines,
),
);
},
),
),
);
然后我使用此函式將繪圖或整個畫布保存為影像檔案:
_save() async {
try {
final boundary = _globalKey.currentContext!.findRenderObject() as RenderRepaintBoundary;
final image = await boundary.toImage();
final byteData = await image.toByteData(format: ui.ImageByteFormat.png);
if (byteData == null) return h.showToast("Failed to process image, please try again!");
final pngBytes = byteData.buffer.asUint8List(byteData.offsetInBytes, byteData.lengthInBytes);
final fileName = "${DateTime.now().millisecondsSinceEpoch}";
if (kIsWeb) {
Navigator.pop(context, [pngBytes]); // this is the bytes to be uploaded to server
} else {
final fileDir = (await getTemporaryDirectory()).path;
final File imgFile;
imgFile = File('$fileDir/$fileName.png');
imgFile.writeAsBytes(pngBytes);
Navigator.pop(context, [imgFile.path]);
}
} catch (e) {
print(e);
}
}
我使用 canvaskit 渲染器運行它:
flutter run -d chrome --web-renderer canvaskit
我懷疑這是閃爍(chrome)畫布或渲染引擎中的錯誤。如何解決這個問題?
截圖:
uj5u.com熱心網友回復:
當前的解決方法是使用 BROWSER_IMAGE_DECODEDING_ENABLED=false 構建:
flutter build web --release --web-renderer canvaskit --dart-define=BROWSER_IMAGE_DECODING_ENABLED=false
似乎是 canvaskit 上的影像解碼器的問題。這樣下去,看起來這面旗幟要消失了。希望到那時我們能解決問題。
哦,據說這在 iOS Safari 上不起作用。看到這個。
編輯:似乎只在發布模式下作業。(在 Chrome 上測驗)
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/492314.html