I have this code which loads a ui.Image using an async function:
Future<ui.Image> _loadImage() async {
final imageData = await rootBundle.load('assets/some_image.jpg');
var imageBytes = imageData.buffer.asUint8List();
return await decodeImageFromList(imageBytes);
}
But I would like to base it on AssetImage instead as it loads the correct asset version for the device pixel density. Or make it resolution aware by some other means.
Related
I am creating a widget in which I want to display a gridview of image clicked through mobile camera at runtime. I had used image_picker package from flutter. But it is only working for picking image from gallery and everytime I click image it crashes.
class _ImageInputState extends State<ImageInput>
with AutomaticKeepAliveClientMixin {
// list of images
final List<File> _imageFileList = [];
final ImagePicker _picker = ImagePicker();
Function for picking image from camera using image_picker
final imageFile = await _picker.pickImage(source: imageSource);
if (imageFile == null) return;
File tmpFile = File(imageFile.path);
final appDir = await getApplicationDocumentsDirectory();
final fileName = basename(imageFile.path);
final localFile = await tmpFile.copy('${appDir.path}/$fileName');
// setState(() {
// _imageFileList.add(localFile);
//
// });
_pickImageGall(ImageSource.gallery);
}
function for picking images from the gallery of phone
Future<void> _pickImageGall(ImageSource imageSource) async {
final _pickedImage = await _picker.pickImage(source: imageSource);
if (_pickedImage != null) {
setState(() {
_imageFileList.add(File(_pickedImage.path));
});
}
}
and in the ui there is a gridview to display the images in which the last index is a input widget where there is two IconButton one for camera input and other for gallery input. As I am making this thing for the first time I am confused how to procedure will be . I had try to implement every solution from the stackoverflow but none worked for me. Please give the solution.
I am trying to make an OBS-like app using Flutter.
I was trying to use Flutter engine to draw widgets onto the video
frames, along with screen, with separated layers.
I came up with a bad way, which:
use RenderRepaintBoundary to get images of specific area.
use ffmpeg to compose these .png series into video with h.264 encoding.
(then maybe use .mp4 files to publish as video stream??)
, which is baaad in real-time performance and efficiency apparently.
(relevant code)
// some_page.dart
int index = 0;
Future<void> onTestPressed() async {
int i = 0;
while (i++ < 600) {
try {
var render = repaintKey.currentContext!.findRenderObject()
as RenderRepaintBoundary;
double dpr = window.devicePixelRatio;
var byteData = await render
.toImage(pixelRatio: dpr)
.then((image) => image.toByteData(format: ImageByteFormat.png));
var tempDir = await getTemporaryDirectory();
var fileName = '${tempDir.path}/frame_${index++}';
var bytes = byteData!.buffer.asUint8List();
var file = File(fileName);
if (!file.existsSync()) {
file.createSync();
}
await file.writeAsBytes(bytes);
// OpenFile.open(fileName);
} catch (e) {
if (kDebugMode) {
print(e);
}
}
}
}
🌟 I know that Flutter uses Skia as its graphic engine, and could I use Skia ability (by drawing widgets) somehow so as to produce video frames more directly?
Thank you.
I want to implement twitter share in my flutter application.
I convert my widget to image by using RepaintBoundary and stored as ByteData as below.
Future<ByteData> convertWidgetToImage(GlobalKey key) async {
final RenderRepaintBoundary boundary =
key.currentContext!.findRenderObject() as RenderRepaintBoundary;
final image = await boundary.toImage();
final byteData = await image.toByteData(format: ui.ImageByteFormat.png);
return byteData!;
}
Then, I want to open twitter app with some default text and with this image data. (I can convert this bytedata to local file path url if needed as below)
Future<String> get _localPath async {
final directory = await getApplicationDocumentsDirectory();
return directory.path;
}
Is there any way I can share this image to twitter (onTap then open twitter app with this image)?
This could be an option but I don't think I can share twitter image
https://pub.dev/packages/social_share
Is there any better way to convert network image to byteData? I am trying to convert network image from firebase url to byteData and here is my code:
Future<Uint8List> _loadNetworkImage() async {
try {
final response = await http.get(imageUrl);
return response.bodyBytes;
} catch (_) {
throw "Couldn't resolve network Image.";
}
}
Currently it takes almost 20+ seconds for a 7mb photo to be converted.
Here is how I ended up doing it.
Future<Uint8List?> _loadNetworkImage(String path) async {
final completer = Completer<ImageInfo>();
var img = NetworkImage(path);
img.resolve(const ImageConfiguration()).addListener(
ImageStreamListener((info, _) => completer.complete(info)));
final imageInfo = await completer.future;
final byteData =
await imageInfo.image.toByteData(format: ui.ImageByteFormat.png);
return byteData?.buffer.asUint8List();
}
I'm using multi_image_picker package to pick images and upload to server, but before uploading I want to resize images. I'm trying to accomplish it using dart.ui but having a problem:
//assets is List<Asset> from MultiImagePicker.pickImages
assets.forEach((asset) {
Future<ByteData> byteData = asset.getByteData();
byteData.then((d) async {
List<int> imageData = d.buffer.asUint8List();
String b64 =base64Encode(imageData);
print(b64); // prints [/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQE...
//if i send b64 to server then decode it and save as img it's working well
//Resize
ui.instantiateImageCodec(imageData,targetHeight: 800, targetWidth: 600)
.then((codec) {
codec.getNextFrame().then((frameInfo) async {
ui.Image i = frameInfo.image;
ByteData bytes = await i.toByteData();
List<int> resizedImageData = bytes.buffer.asUint8List();
String rb64 = base64Encode(resizedImageData);
print(rb64); // prints too many backslashes:[k5KO/5qWk/+ZlZL/mpaT/5uXlP+alpP/mJSR/5iUkf+YlJH/mZSR/5uWk/+blpP/n5qX/6GcmP+gm5f/oZyY/6GcmP+fmpb/nZi..
//If i send rb64 to server then server cannot decode and save it.
});
});
});
});
This is the function I normally use to resize:
import 'dart:ui' as skia;
Future<skia.Image> resizeImage(String path, {int width, int height}) async {
Uint8List data = await File(path).readAsBytes();
final codec = await skia.instantiateImageCodec(data, targetWidth: width, targetHeight: height);
final frame = await codec.getNextFrame();
return frame.image;
}
As I mentioned in the comment, this is currently not working in Flutter Web but it's due to a bug that will be fixed soon, hopefully.