Is it possible to use Google ML-Kit On-Device Text Recognition in Flutter? All of the tutorials and resources I am finding online are all firebase_ml_vision, but I am looking for one that uses the no-cost OCR from Google ML-Kit. How would I do this in Flutter?
as #Sayan Nath said you can use mlkit, but I think the better choice would be google_ml_kit, the firebase team who have worked on firebase_ml_vision also recommended using it.
use this package https://pub.dev/packages/camera_google_ml_vision
It's exactly the same in terms of how to use firebase_ml_vision
Yes surely you can use this package https/pub.dev/packages/mlkit this is google's mlkit. OCR has also support for both ios and android. Happy Coding ;)
ML Kit for Text Recognition
Follow the installation of Google ML Kit (https://pub.dev/packages/google_ml_kit). (Flutter 2.8)
Set this thing up
bool hasImage = false;
File? image;
TextDetector textDetector = GoogleMlKit.vision.textDetector();
String? imagePath;
String scanText = '';
To get the image, use image picker: https://pub.dev/packages/image_picker
Future getImage(ImageSource source) async {
try {
final image = await ImagePicker().pickImage(source: source);
if (image == null) return;
final imageTemporary = File(image.path);
setState(() {
this.image = imageTemporary;
imagePath = imageTemporary.path;
debugPrint(imagePath);
hasImage = true;
});
} on PlatformException catch (e) {
debugPrint('Failed to pick image: $e');
}
}
Code for getting the text from the image
Future getText(String path) async {
final inputImage = InputImage.fromFilePath(path);
final RecognisedText recognisedText =
await textDetector.processImage(inputImage);
for (TextBlock block in recognisedText.blocks) {
for (TextLine line in block.lines) {
for (TextElement element in line.elements) {
setState(() {
scanText = scanText + ' ' + element.text;
debugPrint(scanText);
});
}
scanText = scanText + '\n';
}
}
}
Call the getText function and pass the image path. getText(imagePath).
Related
im learning flutter and now tried to capture the photo with ImagePicker package from the following method, but after I successfully capture the photo, there is always 1 sec until app get the data and jump to next page:
Future pickImage(ImageSource source) async {
try {
var image = await ImagePicker().pickImage(source: source);
if (image == null) return;
final imagePermanent = await saveImagePermanently(image.path);
selectedImage = File(imagePermanent.path);
isUploaded.value = !isUploaded.value;
update();
} on PlatformException catch (e) {
print('Failed to pick image: $e');
}
}
Future<File> saveImagePermanently(String imagePath) async {
final directory = await getApplicationDocumentsDirectory();
final name = basename(imagePath);
final image = File('${directory.path}/$name');
return File(imagePath).copy(image.path);
}
now my solution is adding a listener onInit when image is created with GetX:
#override
void onInit() {
super.onInit();
ever(isUploaded, (value) {
Get.to(
() => AddPersonProfileAddDetails(),
);
});
}
So is there a way to detect the status of capturing the image like finished/failed/progressing, thanks for any clue or let me know a better way to jump to next page after capturing the image, thanks a lot!
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.
Plug-in functions return version in imagepath.
same behaviour in all these functions getImagesPath() ,getVideoPath(),getAudioPath(),getFilePath().
Plug in: https://pub.dev/packages/storage_path , storage_path: ^0.2.0
Future<void> getImagesPath() async {
String imagespath = "";
try {
**imagespath = await StoragePath.imagesPath;** // return IOS Version (Example: Ios 15.2)
var response = jsonDecode(imagespath);
print(response);
var imageList = response as List;
List<FileModel> list = imageList.map<FileModel>((json) => FileModel.fromJson(json)).toList();
setState(() {
imagePath = list[11].files[0];
});
} on PlatformException {
imagespath = 'Failed to get path';
}
return imagespath;
}
I got it. Actually, I missed reading the Readme file. This plug-in is only available with android.
ONLY FOR ANDROID
I want to resize an image and when run my code but resize process is very slow.
My code as below :
void _selectImage() async {
try {
final checkDataImage =
await _imagePicker.pickImage(source: ImageSource.camera);
if (checkDataImage != null) {
print(checkDataImage.name);
print(checkDataImage.path);
setState(() {
pickedImage = checkDataImage;
});
}
} catch (err) {
print(err);
pickedImage = null;
}
final tempDir = await getTemporaryDirectory();
final path = tempDir.path;
Img.Image image = Img.decodeImage(await pickedImage.readAsBytes());
Img.Image smallerImg = Img.copyResize(image, width: 500);
int rand = new Math.Random().nextInt(999999999);
var compressImg = new File('$path/image_$rand.jpg')
..writeAsBytesSync(Img.encodeJpg(smallerImg, quality: 90));
setState(() {
if (!mounted) return;
_imageUpload = compressImg;
});}
What wrong my code, please help to faster it process ?
Thank you for your help.
As others have said, package:image is written in pure Dart and will never be as fast as native solutions that can be multithreaded and hardware accelerated.
While using another isolate will stop the image tasks blocking the UI, if you need to do this as fast as possible, I suggest you use something like the ImageMagick library, or if you only need Android and iOS support, package:flutter_image_compress.
Flutter 2 announced just few days ago and some packages updated for web like Image Picker. I'm trying to get image and upload it to cloud storage. Image picker working very well but when
I want to upload image to storage it gives me error.
Unsupported operation: Platform._operatingSystem
UI Code
onImageSelect: (selectedImage) async {
try {
final url = await Get.find<FirebaseStorageService>()
.uploadProfilePicture(
customer.uuid, File(selectedImage.path));
print(url);
} catch (e) {
print(e);
}
customer.profileImageUrl = selectedImage.path;
_isImageSelected = true;
}),
Service Class funciton:
class FirebaseStorageService {
final FirebaseStorage _firebaseStorage = FirebaseStorage.instance;
Reference _storageReference;
Future<String> uploadProfilePicture(
String userID, File uploadingImagePath) async {
_storageReference = _firebaseStorage
.ref()
.child(userID)
.child('images')
.child("profile-photo.png");
var uploadTask = _storageReference.putFile(uploadingImagePath);
var url = await (await uploadTask).ref.getDownloadURL();
return url;
}
}
I tried flutter clean and flutter upgrade. I also searched old questions and some of them used html.File instead of dart:io library but firebase_storage:7.0.0 package only accept File class which is from dart:io library.
Code work on Android and IOS but not web.
I'm using stable channel.