【发布时间】:2021-04-19 03:37:06
【问题描述】:
我认为我的问题很简单,但我无法在任何地方找到答案。我将 ImageProvider 传递给我的 PixelData 类,以便能够访问单个像素颜色值,但我需要从 ImageProvider 中获取 ui.Image 和图像字节数据。我遇到了下面显示的问题,如果不将 createLocalImageConfiguration(buildContext) 与当前的 BuildContext 一起使用,我将无法访问这些值。我希望能够在 BuildContext 范围之外使用此类,因此我需要能够在没有 BuildContext 的情况下获取图像数据。
非常感谢任何有关此问题的帮助/指导。
谢谢!
class PixelData {
ImageProvider imageProvider;
ui.Image _image;
ByteData _byteData;
int _width;
int _height;
PixelData(this.imageProvider) : assert(imageProvider != null);
int get width => _width;
int get height => _height;
Future<void> getByteData() async {
if (imageProvider == null) throw Exception("imageProvider is null");
// TODO here lies the problem.
// TODO how can I provide an ImageConfiguration without BuildContext?
// I can't use: createLocalImageConfiguration(buildContext)
imageProvider.resolve(configuration).addListener(
ImageStreamListener(
(info, _) async {
_image = info.image;
_width = _image.width;
_height = _image.height;
_byteData =
await _image.toByteData(format: ui.ImageByteFormat.rawRgba);
},
),
);
}
void getColorAt() {
// TODO
}
}
我尝试使用 ImageConfiguration.empty,建议在上下文不可用时使用。
这是相关的更新代码和尝试运行后出现的错误。
/// getByteData must be called before trying to access pixel data
Future<void> getByteData() async {
if (imageProvider == null) throw Exception("imageProvider is null");
imageProvider.resolve(ImageConfiguration.empty).addListener(
ImageStreamListener(
(info, _) async {
print("code reached");
_image = info.image;
_width = _image.width;
_height = _image.height;
_byteData =
await _image.toByteData(format: ui.ImageByteFormat.rawRgba);
},
),
);
}
/// Pixel coordinates: (0,0) → (width-1, height-1).
Color pixelColorAt(int x, int y) {
if (_byteData == null ||
width == null ||
height == null ||
x < 0 ||
x >= width ||
y < 0 ||
y >= height)
return null;
else {
var byteOffset = 4 * (x + (y * width));
return _colorAtByteOffset(byteOffset);
}
}
test('test network image', () async {
String url =
"https://i0.wp.com/www.dignited.com/wp-content/uploads/2012/09/Magazine-QR-Code.jpg?fit=500%2C404&ssl=1";
final PixelData pixelData = PixelData(imageProvider: NetworkImage(url));
await pixelData.getByteData();
Color a = pixelData.pixelColorAt(282, 287);
Color b = pixelData.pixelColorAt(218, 105);
Color c = pixelData.pixelColorAt(160, 93);
Color d = pixelData.pixelColorAt(-1, 100);
print(a.value);
print(b.value);
print(c.value);
expect(d, null);
});
══╡ EXCEPTION CAUGHT BY IMAGE RESOURCE SERVICE ╞════════════════════════════════════════════════════
The following _CastError was thrown while resolving an image:
Null check operator used on a null value
When the exception was thrown, this was the stack:
#0 ImageProvider.resolveStreamForKey (package:flutter/src/painting/image_provider.dart:502:69)
#1 ImageProvider.resolve.<anonymous closure> (package:flutter/src/painting/image_provider.dart:333:9)
#2 ImageProvider._createErrorHandlerAndKey.<anonymous closure>.<anonymous closure> (package:flutter/src/painting/image_provider.dart:463:26)
#3 SynchronousFuture.then (package:flutter/src/foundation/synchronous_future.dart:41:35)
#4 ImageProvider._createErrorHandlerAndKey.<anonymous closure> (package:flutter/src/painting/image_provider.dart:460:11)
#8 ImageProvider._createErrorHandlerAndKey (package:flutter/src/painting/image_provider.dart:452:16)
#9 ImageProvider.resolve (package:flutter/src/painting/image_provider.dart:330:5)
#10 PixelData.getByteData (package:pixel_data/simplifying_image_pixels.dart:26:19)
#11 main.<anonymous closure> (file:///Users/graysonharrington/Documents/Programming/Flutter/apps/pixel_data/test/pixel_data_test.dart:14:21)
#12 Declarer.test.<anonymous closure>.<anonymous closure> (package:test_api/src/backend/declarer.dart:175:19)
<asynchronous suspension>
#13 Declarer.test.<anonymous closure>.<anonymous closure> (package:test_api/src/backend/declarer.dart)
#18 Declarer.test.<anonymous closure> (package:test_api/src/backend/declarer.dart:173:13)
#19 Invoker.waitForOutstandingCallbacks.<anonymous closure> (package:test_api/src/backend/invoker.dart:231:15)
#24 Invoker.waitForOutstandingCallbacks (package:test_api/src/backend/invoker.dart:228:5)
#25 Invoker._onRun.<anonymous closure>.<anonymous closure>.<anonymous closure> (package:test_api/src/backend/invoker.dart:383:17)
<asynchronous suspension>
#26 Invoker._onRun.<anonymous closure>.<anonymous closure>.<anonymous closure> (package:test_api/src/backend/invoker.dart)
#31 Invoker._onRun.<anonymous closure>.<anonymous closure> (package:test_api/src/backend/invoker.dart:370:9)
#32 Invoker._guardIfGuarded (package:test_api/src/backend/invoker.dart:415:15)
#33 Invoker._onRun.<anonymous closure> (package:test_api/src/backend/invoker.dart:369:7)
#40 Invoker._onRun (package:test_api/src/backend/invoker.dart:368:11)
#41 LiveTestController.run (package:test_api/src/backend/live_test_controller.dart:153:11)
#42 RemoteListener._runLiveTest.<anonymous closure> (package:test_api/src/remote_listener.dart:256:16)
#47 RemoteListener._runLiveTest (package:test_api/src/remote_listener.dart:255:5)
#48 RemoteListener._serializeTest.<anonymous closure> (package:test_api/src/remote_listener.dart:208:7)
#66 _GuaranteeSink.add (package:stream_channel/src/guarantee_channel.dart:125:12)
#67 new _MultiChannel.<anonymous closure> (package:stream_channel/src/multi_channel.dart:159:31)
#71 CastStreamSubscription._onData (dart:_internal/async_cast.dart:85:11)
#105 new _WebSocketImpl._fromSocket.<anonymous closure> (dart:_http/websocket_impl.dart:1145:21)
#113 _WebSocketProtocolTransformer._messageFrameEnd (dart:_http/websocket_impl.dart:338:23)
#114 _WebSocketProtocolTransformer.add (dart:_http/websocket_impl.dart:232:46)
#124 _Socket._onData (dart:io-patch/socket_patch.dart:2044:41)
#133 new _RawSocket.<anonymous closure> (dart:io-patch/socket_patch.dart:1580:33)
#134 _NativeSocket.issueReadEvent.issue (dart:io-patch/socket_patch.dart:1076:14)
(elided 104 frames from dart:async and package:stack_trace)
Image provider:
NetworkImage("https://i0.wp.com/www.dignited.com/wp-content/uploads/2012/09/Magazine-QR-Code.jpg?fit=500%2C404&ssl=1",
scale: 1.0)
Image configuration: ImageConfiguration()
Image key:
NetworkImage("https://i0.wp.com/www.dignited.com/wp-content/uploads/2012/09/Magazine-QR-Code.jpg?fit=500%2C404&ssl=1",
scale: 1.0)
════════════════════════════════════════════════════════════════════════════════════════════════════
pixelColorAt() 函数之前已经使用 ui.Image 对象进行了测试,并且可以按预期工作。我只是想让该类使用 ImageProvider 构造函数变量而不是 ui.Image。
【问题讨论】: