如何在 Flutter 中显示从 .NET Core API 加载的 jpeg 图像?
How to display jpeg image loaded from .NET Core API in Flutter?
我正在尝试显示从 .NET Core 网络加载的 jpeg 图像 API。但是,似乎我在编码方面做错了什么。有时我没有收到任何错误,但图像不可见且未显示。有时我会收到以下错误:
Could not instantiate image codec.
我尝试了几种方法来显示图像,但都没有成功。
包含 jpeg 图片的网络 API 响应:
显示图片的应用页面截图:
从API加载图像的代码:
Future<Uint8List> _loadFileBytes(String fileId) async {
var bytesResponse = await fileHttpService.getFileBytes(fileId);
if (bytesResponse.statusCode != 200) _handlePhotoLoadError();
var bytesStr = bytesResponse.body;
var bytes = utf8.encode(bytesStr);
return bytes;
}
接收照片中 jpeg 图像字节的 Widget 代码 属性 试图显示它:
import 'package:flutter/material.dart';
import 'package:.../models/PhotoModel.dart';
import 'package:image/image.dart' as imageUtils;
class PhotoView extends StatefulWidget {
final PhotoModel photo;
PhotoView({@required this.photo});
@override
PhotoViewState createState() => PhotoViewState();
}
class PhotoViewState extends State<PhotoView> {
double displayHeight;
double displayWidth;
@override
void initState() {
displayHeight = 1;
displayWidth = 1;
super.initState();
}
@override
Widget build(BuildContext context) {
displayHeight = MediaQuery.of(context).size.height;
displayWidth = MediaQuery.of(context).size.width;
return Container(
child: Stack(
children: <Widget>[
Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Flexible(
flex: 18,
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.all(
Radius.circular(displayWidth * 0.1)),
boxShadow: [
BoxShadow(
blurRadius: displayWidth * 0.05,
color: Color.fromRGBO(0, 0, 0, 0.5),
offset: Offset(
displayWidth * 0.01, displayWidth * 0.025))
]),
child: ClipRRect(
borderRadius: BorderRadius.all(
Radius.circular(displayWidth * 0.015)),
child: _futureBuildImage()),
)),
]),
],
));
}
void deleteButtonPressed() {
showMessageDialog("", "Säker på att du vill radera fotot?");
print("Delete button pressed!!!");
}
void showMessageDialog(String title, String body) {
try {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: new Text(body),
content: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Expanded(
child: FlatButton(
onPressed: deleteDialogYesPressed,
child: Text("Radera"),
),
),
Expanded(
child: FlatButton(
onPressed: deleteDialogNoPressed,
child: Text("Avbryt"),
))
],
),
);
});
} catch (e) {
print(e.toString());
}
}
void deleteDialogYesPressed() {
Navigator.pop(context);
}
void deleteDialogNoPressed() {
Navigator.pop(context);
}
Widget _futureBuildImage() {
var futureBuilder = FutureBuilder<Widget>(
future: _decodeImage(),
initialData: Container(),
builder: _createImage,
);
return futureBuilder;
}
Future<Widget> _decodeImage() async {
try {
var byteData =
await (await decodeImageFromList(widget.photo.bytes)).toByteData();
var bytes = byteData.buffer.asUint8List();
var image = Image.memory(bytes);
return image;
} catch (e) {
return Container();
}
}
Widget _createImage(BuildContext context, AsyncSnapshot<Widget> snapshot) {
if (snapshot.connectionState == ConnectionState.none ||
snapshot.connectionState == ConnectionState.active ||
snapshot.connectionState == ConnectionState.waiting)
return Container();
else if (snapshot.connectionState == ConnectionState.done)
return snapshot.data;
else
return Container();
}
}
如果你想知道为什么我用 utf8 编码字节串,这只是我尝试过的另一种方法。我不知道应该如何显示网络 API 响应中收到的图像。
这让我抓狂。
感谢您的帮助!
在尝试了不同的方法后,我终于找到了一个非常简单的解决方案。我不明白为什么我从一开始就没有让它以这种方式工作。这很简单。
以下是可能遇到相同问题的其他人的步骤:
第一步,通过Response.bodyBytes
属性获取字节:
Future<Uint8List> _loadFileBytes(String fileId) async {
var bytesResponse = await fileHttpService.getFileBytes(fileId);
if (bytesResponse.statusCode != 200) _handlePhotoLoadError();
var bytes = bytesResponse.bodyBytes;
return bytes;
}
第 2 步,只需将 int 数组传递给 Image.memory()
方法即可。
child: Image.memory(widget.photo.bytes)
我现在觉得自己像个白痴。希望这至少可以帮助其他人面临同样的问题。德普
我正在尝试显示从 .NET Core 网络加载的 jpeg 图像 API。但是,似乎我在编码方面做错了什么。有时我没有收到任何错误,但图像不可见且未显示。有时我会收到以下错误:
Could not instantiate image codec.
我尝试了几种方法来显示图像,但都没有成功。
包含 jpeg 图片的网络 API 响应:
显示图片的应用页面截图:
从API加载图像的代码:
Future<Uint8List> _loadFileBytes(String fileId) async {
var bytesResponse = await fileHttpService.getFileBytes(fileId);
if (bytesResponse.statusCode != 200) _handlePhotoLoadError();
var bytesStr = bytesResponse.body;
var bytes = utf8.encode(bytesStr);
return bytes;
}
接收照片中 jpeg 图像字节的 Widget 代码 属性 试图显示它:
import 'package:flutter/material.dart';
import 'package:.../models/PhotoModel.dart';
import 'package:image/image.dart' as imageUtils;
class PhotoView extends StatefulWidget {
final PhotoModel photo;
PhotoView({@required this.photo});
@override
PhotoViewState createState() => PhotoViewState();
}
class PhotoViewState extends State<PhotoView> {
double displayHeight;
double displayWidth;
@override
void initState() {
displayHeight = 1;
displayWidth = 1;
super.initState();
}
@override
Widget build(BuildContext context) {
displayHeight = MediaQuery.of(context).size.height;
displayWidth = MediaQuery.of(context).size.width;
return Container(
child: Stack(
children: <Widget>[
Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Flexible(
flex: 18,
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.all(
Radius.circular(displayWidth * 0.1)),
boxShadow: [
BoxShadow(
blurRadius: displayWidth * 0.05,
color: Color.fromRGBO(0, 0, 0, 0.5),
offset: Offset(
displayWidth * 0.01, displayWidth * 0.025))
]),
child: ClipRRect(
borderRadius: BorderRadius.all(
Radius.circular(displayWidth * 0.015)),
child: _futureBuildImage()),
)),
]),
],
));
}
void deleteButtonPressed() {
showMessageDialog("", "Säker på att du vill radera fotot?");
print("Delete button pressed!!!");
}
void showMessageDialog(String title, String body) {
try {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: new Text(body),
content: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Expanded(
child: FlatButton(
onPressed: deleteDialogYesPressed,
child: Text("Radera"),
),
),
Expanded(
child: FlatButton(
onPressed: deleteDialogNoPressed,
child: Text("Avbryt"),
))
],
),
);
});
} catch (e) {
print(e.toString());
}
}
void deleteDialogYesPressed() {
Navigator.pop(context);
}
void deleteDialogNoPressed() {
Navigator.pop(context);
}
Widget _futureBuildImage() {
var futureBuilder = FutureBuilder<Widget>(
future: _decodeImage(),
initialData: Container(),
builder: _createImage,
);
return futureBuilder;
}
Future<Widget> _decodeImage() async {
try {
var byteData =
await (await decodeImageFromList(widget.photo.bytes)).toByteData();
var bytes = byteData.buffer.asUint8List();
var image = Image.memory(bytes);
return image;
} catch (e) {
return Container();
}
}
Widget _createImage(BuildContext context, AsyncSnapshot<Widget> snapshot) {
if (snapshot.connectionState == ConnectionState.none ||
snapshot.connectionState == ConnectionState.active ||
snapshot.connectionState == ConnectionState.waiting)
return Container();
else if (snapshot.connectionState == ConnectionState.done)
return snapshot.data;
else
return Container();
}
}
如果你想知道为什么我用 utf8 编码字节串,这只是我尝试过的另一种方法。我不知道应该如何显示网络 API 响应中收到的图像。
这让我抓狂。 感谢您的帮助!
在尝试了不同的方法后,我终于找到了一个非常简单的解决方案。我不明白为什么我从一开始就没有让它以这种方式工作。这很简单。 以下是可能遇到相同问题的其他人的步骤:
第一步,通过Response.bodyBytes
属性获取字节:
Future<Uint8List> _loadFileBytes(String fileId) async {
var bytesResponse = await fileHttpService.getFileBytes(fileId);
if (bytesResponse.statusCode != 200) _handlePhotoLoadError();
var bytes = bytesResponse.bodyBytes;
return bytes;
}
第 2 步,只需将 int 数组传递给 Image.memory()
方法即可。
child: Image.memory(widget.photo.bytes)
我现在觉得自己像个白痴。希望这至少可以帮助其他人面临同样的问题。德普