Load a ui.Image asset based on pixel density - flutter

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

Can't able to save and display camera images in gridView in flutter using image_picker

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.

How to compose (encoded) pixels into videos / live-streams in Flutter?

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.

How to implement twitter share with image file in flutter

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

Flutter Converting network image into byteData

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();
}

How to resize image using multi_image_picker in Flutter?

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.