Flutter 如何在Flatter Web中在Blob和Image之间来回转换? 上下文
我使用带有颤振web的图像选择器来允许用户选择图像。这将返回本地网络Blob对象的URI,我可以使用Flutter 如何在Flatter Web中在Blob和Image之间来回转换? 上下文,flutter,dart,flutter-web,dart-html,Flutter,Dart,Flutter Web,Dart Html,我使用带有颤振web的图像选择器来允许用户选择图像。这将返回本地网络Blob对象的URI,我可以使用Image.network(pickedFile.path)显示该对象。我遇到的麻烦是当我想开始操纵图像时。首先,我需要把它从网络中拉出来,放到内存中。完成后,我需要将其推回到网络可访问的Blob 如何从图像创建水滴? 我不是指内置的图像小部件。我指的是ImageLib.Image,其中ImageLib是。我为什么要这样做?我有一个web应用程序,用户在其中选择一个图像,该图像作为Blob返回。我
Image.network(pickedFile.path)
显示该对象。我遇到的麻烦是当我想开始操纵图像时。首先,我需要把它从网络中拉出来,放到内存中。完成后,我需要将其推回到网络可访问的Blob
如何从图像创建水滴?
我不是指内置的图像小部件。我指的是ImageLib.Image,其中ImageLib是。我为什么要这样做?我有一个web应用程序,用户在其中选择一个图像,该图像作为Blob返回。我将其放入内存,使用ImageLib裁剪并调整其大小,然后将其推回到Blob URL。这是我的代码当前所在的位置:
# BROKEN:
var png = ImageLib.encodePng(croppedImage);
var blob = html.Blob([base64Encode(png)], 'image/png');
var url = html.Url.createObjectUrl(blob);
在我尝试使用image(image:NetworkImage(url))
显示图像之前,代码不会抛出错误。错误开始于:
解析图像帧时引发了以下事件$object:
将url
复制并粘贴到浏览器中会显示一个黑屏,我认为这是一个0x0图像。因此,我提出了我的问题:
image\u picker
获取文件名,并使用包:image/image.dart as ImageLib
对其进行操作:
// pickedfile.path is the name of a file
ImageLib.Image img = ImageLib.decodeImage(File(pickedfile.path).readAsBytesSync());
对于web,我没有文件系统访问权限,因此我一直在这样做:
// pickedfile.path is the URL of an HTML Blob
var response = await http.get(pickedfile.path);
ImageLib.Image img = ImageLib.decodeImage(response.bodyBytes);
这比旧方法慢得多,可能是因为GET。这真的是将图像存储到内存中的最佳(或唯一)方法吗?正如Brendan Duncan所说,秘密在于使用浏览器的本机解码功能:
// user browser to decode
html.ImageElement myImageElement = html.ImageElement(src: imagePath);
await myImageElement.onLoad.first; // allow time for browser to render
html.CanvasElement myCanvas = html.CanvasElement(width: myImageElement.width, height: myImageElement.height);
html.CanvasRenderingContext2D ctx = myCanvas.context2D;
//ctx.drawImage(myImageElement, 0, 0);
//html.ImageData rgbaData = ctx.getImageData(0, 0, myImageElement.width, myImageElement.height);
// resize to save time on encoding
int _MAXDIM = 500;
int width, height;
if (myImageElement.width > myImageElement.height) {
width = _MAXDIM;
height = (_MAXDIM*myImageElement.height/ myImageElement.width).round();
} else {
height = _MAXDIM;
width = (_MAXDIM*myImageElement.width/ myImageElement.height).round();
}
ctx.drawImageScaled(myImageElement, 0, 0, width, height);
html.ImageData rgbaData = ctx.getImageData(0, 0, width, height);
var myImage = ImageLib.Image.fromBytes(rgbaData.width, rgbaData.height, rgbaData.data);
他提出了一个类似的编码技巧,但对于我的用例来说,使用Dart就足够了:
int width, height;
if (myImageElement.width > myImageElement.height) {
width = 800;
height = (800*myImageElement.height/ myImageElement.width).round();
} else {
height = 800;
width = (800*myImageElement.width/ myImageElement.height).round();
}
ctx.drawImageScaled(myImageElement, 0, 0, width, height);
html.ImageData rgbaData = ctx.getImageData(0, 0, width, height);
var myImage = ImageLib.Image.fromBytes(rgbaData.width, rgbaData.height, rgbaData.data);
请注意,在这两种情况下,我都会首先调整图像的大小以减小大小。正如Brendan Duncan所说,秘密在于使用浏览器的本机解码功能:
// user browser to decode
html.ImageElement myImageElement = html.ImageElement(src: imagePath);
await myImageElement.onLoad.first; // allow time for browser to render
html.CanvasElement myCanvas = html.CanvasElement(width: myImageElement.width, height: myImageElement.height);
html.CanvasRenderingContext2D ctx = myCanvas.context2D;
//ctx.drawImage(myImageElement, 0, 0);
//html.ImageData rgbaData = ctx.getImageData(0, 0, myImageElement.width, myImageElement.height);
// resize to save time on encoding
int _MAXDIM = 500;
int width, height;
if (myImageElement.width > myImageElement.height) {
width = _MAXDIM;
height = (_MAXDIM*myImageElement.height/ myImageElement.width).round();
} else {
height = _MAXDIM;
width = (_MAXDIM*myImageElement.width/ myImageElement.height).round();
}
ctx.drawImageScaled(myImageElement, 0, 0, width, height);
html.ImageData rgbaData = ctx.getImageData(0, 0, width, height);
var myImage = ImageLib.Image.fromBytes(rgbaData.width, rgbaData.height, rgbaData.data);
他提出了一个类似的编码技巧,但对于我的用例来说,使用Dart就足够了:
int width, height;
if (myImageElement.width > myImageElement.height) {
width = 800;
height = (800*myImageElement.height/ myImageElement.width).round();
} else {
height = 800;
width = (800*myImageElement.width/ myImageElement.height).round();
}
ctx.drawImageScaled(myImageElement, 0, 0, width, height);
html.ImageData rgbaData = ctx.getImageData(0, 0, width, height);
var myImage = ImageLib.Image.fromBytes(rgbaData.width, rgbaData.height, rgbaData.data);
请注意,在这两种情况下,我都会先调整图像大小以减小大小。有相同的问题,您解决了吗?请参阅下面的答案。有相同的问题,您解决了吗?请参阅下面的答案。如何使用dio将其发送到服务器多部分?我正在上载到Firebase。我首先按照上面的方式对图像进行编码,然后:``//encodeasjpgstringcontenttype='image/jpeg';var jpg=ImageLib.encodeJpg(img,质量:90);//上传至firebase存储字符串url;请尝试{fb.StorageReference}fb.storage().ref(imageKey);fb.UploadTaskSnapshot UploadTaskSnapshot=await{u storage.put(jpg,fb.UploadMetadata(contentType:contentType)).future;var-imageUri=await UploadTaskSnapshot.ref.getDownloadURL();url=imageUri.toString()}catch(e){print(e);}``我如何使用dio将其发送到服务器Multipart?我正在上传到Firebase。我首先按照上面的方式对图像进行编码,然后:``//encodeasjpgstringcontenttype='image/jpeg';var jpg=ImageLib.encodeJpg(img,质量:90);//上传至firebase存储字符串url;请尝试{fb.StorageReference}fb.storage().ref(imageKey);fb.UploadTaskSnapshot UploadTaskSnapshot=await{u storage.put(jpg,fb.UploadMetadata(contentType:contentType)).future;var-imageUri=await UploadTaskSnapshot.ref.getDownloadURL();url=imageUri.toString()}catch(e){print(e);}```