How to get multiImagePicker2 Asset object from File object in Flutter? - image

To get images from phone gallery,, Using MultiImagePicker2 package https://pub.dev/packages/multi_image_picker2
you get The Images in Object of type Asset,, then you usually transform the ByteData into a File to use it around ,, using the below method,, you get File from Asset.
import 'dart:io';
import 'package:bldrs/controllers/drafters/text_manipulators.dart';
import 'package:flutter/services.dart';
import 'package:multi_image_picker2/multi_image_picker2.dart';
import 'package:path_provider/path_provider.dart';
Future<File> getFileFromAsset(Asset asset) async {
ByteData _byteData = await asset.getThumbByteData(asset.originalWidth, asset.originalHeight, quality: 100);
String _name = TextMod.trimTextAfterLastSpecialCharacter(asset.name, '.');
print('asset name is : ${asset.runtimeType}');
final _tempFile = File('${(await getTemporaryDirectory()).path}/${_name}');
await _tempFile.writeAsBytes(_byteData.buffer.asUint8List(_byteData.offsetInBytes, _byteData.lengthInBytes));
await _tempFile.create(recursive: true);
File _file = _tempFile;
return _file;
}
so my question is..
Can you reverse this method,, to get Asset from File instead ?

Related

I am searching for a Flutter package which can find the barcode of a .pdf file

I am trying to build an application on Windows, which i pick (.pdf) files that contain a barcode on them.
I want to find and extract the barcode info and put it on a list.
I need a package that it can make it happen. A package except https://pub.dev/packages/flutter_barcode_sdk because it has an annually cost for its licence.
I spent some time writing this for you and I made it using two different packages.
This one is able to read barcodes from camera and files
scan: 1.6.0
But I could not make it read PDFs, so I installed another package to render images from PDF files.
native_pdf_renderer: 3.1.0
This package is also required:
path_provider: ^2.0.11
This is the code that worked fine for me:
import 'dart:async';
import 'dart:io';
import 'package:native_pdf_renderer/native_pdf_renderer.dart';
import 'package:path_provider/path_provider.dart';
import 'package:scan/scan.dart';
Future<void> readBarcodeFromPDF(String assetPath) async {
PdfDocument pdf = await PdfDocument.openAsset(assetPath);
for (var pageIndex = 0; pageIndex < pdf.pagesCount; pageIndex++) {
final page = await pdf.getPage(pageIndex);
final image = await page.render(width: 2048, height: 2048);
if (image != null) {
final byteData = image.bytes;
final file = File('${(await getTemporaryDirectory()).path}/barcodes');
await file.writeAsBytes(byteData.buffer.asUint8List(byteData.offsetInBytes, byteData.lengthInBytes));
String? barcode = await Scan.parse(file.path);
if (barcode == null) {
print("barcode not found in page $pageIndex");
} else {
print("Barcode Found: $barcode in page $pageIndex");
}
}
}
}

How to load network image in Flame?

In Flame documentation, Image class just load from asset folder.
bgSprite = Sprite('avatar/avatar-sample.png');
How can I load network images in Flame.
You could do something like this in versions after 1.0.0:
import dart:ui; // This is the package you want the Image class from, there are several
Future<Image> getImage(String path) async {
Completer<ImageInfo> completer = Completer();
var img = new NetworkImage(path);
img.resolve(ImageConfiguration()).addListener(ImageStreamListener((ImageInfo info,bool _){
completer.complete(info);
}));
ImageInfo imageInfo = await completer.future;
return imageInfo.image;
}
and then in your onLoad method, just initiate bgSprite:
#override
Future<void> onLoad() async {
final image = await getImage("your-url.com/sample.png");
bgSprite = Sprite(image);
}
In 0.28.0, which it looks like you are running, you'll just replace the last line with (but I really recommend upgrading to a version after 1.0.0):
bgSprite = Sprite.fromImage(image);

Flutter image save get blurred in iOS

I have created a sample app that saves a container as an image using flutter. This works totally fine with the android device and the saved image is of good quality. However, when I check this in the iPhone (emulator and physical device) the saved image is not in good quality.
Below is the code that I have used to save the container as an image and I just pass the global key of my container that needs to save.
import 'dart:math';
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'dart:ui' as ui;
import 'dart:io' as Io;
import 'package:path_provider/path_provider.dart';
import 'package:gallery_saver/gallery_saver.dart';
class ImageExport {
save(GlobalKey globalKey) async {
Random random = new Random();
int randomNumber = random.nextInt(1000);
RenderRepaintBoundary boundary =
globalKey.currentContext.findRenderObject();
ui.Image image = await boundary.toImage(pixelRatio: 5.0);
final directory = (await getApplicationDocumentsDirectory()).path;
ByteData byteData = await image.toByteData(format: ui.ImageByteFormat.png);
Uint8List pngBytes = byteData.buffer.asUint8List();
Io.File imgFile = new Io.File('$directory/test$randomNumber.jpg');
imgFile.writeAsBytes(pngBytes);
imgFile.writeAsBytesSync(pngBytes);
GallerySaver.saveImage(imgFile.path, albumName: "test");
}
}
Could some please help me resolve this issue?

error in projecting a shapefile from epsg:4326 to epsg:32056

I have been trying to change the projection of Shapefile from one coordinate reference system to other. The shapefile I have used has EPSG:4326 as its reference system and I need to change it to EPSG:32056.
I am using Geotools API-20.0 for the same.
I have already tried various methods available in the geotools like using ReprojectingFeatureCollection, use of JTS, use of Query API to convert the shapefile directly to the other coordinate reference system
import java.awt.event.ActionEvent;
import java.io.File;
import java.io.InputStream;
import java.io.Serializable;
import java.net.URI;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import javax.swing.Action;
import javax.swing.JButton;
import javax.swing.JOptionPane;
import javax.swing.JToolBar;
import javax.swing.SwingWorker;
import org.geotools.data.DataStore;
import org.geotools.data.DataStoreFactorySpi;
import org.geotools.data.DefaultTransaction;
import org.geotools.data.FeatureWriter;
import org.geotools.data.FileDataStore;
import org.geotools.data.FileDataStoreFinder;
import org.geotools.data.Query;
import org.geotools.data.Transaction;
import org.geotools.data.shapefile.ShapefileDataStoreFactory;
import org.geotools.data.simple.SimpleFeatureCollection;
import org.geotools.data.simple.SimpleFeatureIterator;
import org.geotools.data.simple.SimpleFeatureSource;
import org.geotools.data.simple.SimpleFeatureStore;
import org.geotools.feature.simple.SimpleFeatureTypeBuilder;
import org.geotools.geometry.jts.JTS;
import org.geotools.geometry.jts.ReferencedEnvelope;
import org.geotools.map.FeatureLayer;
import org.geotools.map.Layer;
import org.geotools.map.MapContent;
import org.geotools.referencing.CRS;
import org.geotools.referencing.ReferencingFactoryFinder;
import org.geotools.referencing.factory.gridshift.GridShiftLocator;
import org.geotools.styling.SLD;
import org.geotools.styling.Style;
import org.geotools.swing.JMapFrame;
import org.geotools.swing.JProgressWindow;
import org.geotools.swing.action.SafeAction;
import org.geotools.swing.data.JFileDataStoreChooser;
import org.locationtech.jts.geom.Envelope;
import org.opengis.feature.Feature;
import org.opengis.feature.FeatureVisitor;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;
import org.opengis.feature.type.FeatureType;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.opengis.referencing.operation.MathTransform;
import org.opengis.util.ProgressListener;
import com.vividsolutions.jts.geom.Geometry;
public class CRSLab {
private File sourceFile;
private SimpleFeatureSource featureSource;
private MapContent map;
public static void main(String[] args) throws Exception {
CRSLab lab = new CRSLab();
lab.displayShapefile();
}
// docs end main
/**
* This method:
* <ol type="1">
* <li>Prompts the user for a shapefile to display
* <li>Creates a JMapFrame with custom toolbar buttons
* <li>Displays the shapefile
* </ol>
*/
// docs start display
private void displayShapefile() throws Exception {
sourceFile = JFileDataStoreChooser.showOpenFile("shp", null);
if (sourceFile == null) {
return;
}
FileDataStore store = FileDataStoreFinder.getDataStore(sourceFile);
featureSource = store.getFeatureSource();
// Create a map context and add our shapefile to it
map = new MapContent();
Style style = SLD.createSimpleStyle(featureSource.getSchema());
Layer layer = new FeatureLayer(featureSource, style);
map.layers().add(layer);
// Create a JMapFrame with custom toolbar buttons
JMapFrame mapFrame = new JMapFrame(map);
mapFrame.enableToolBar(true);
mapFrame.enableStatusBar(true);
JToolBar toolbar = mapFrame.getToolBar();
toolbar.addSeparator();
toolbar.add(new JButton(new ValidateGeometryAction()));
toolbar.add(new JButton(new ExportShapefileAction()));
// Display the map frame. When it is closed the application will exit
mapFrame.setSize(800, 600);
mapFrame.setVisible(true);
}
// docs end display
// docs start export
private void exportToShapefile() throws Exception {
SimpleFeatureType schema = featureSource.getSchema();
JFileDataStoreChooser chooser = new JFileDataStoreChooser("shp");
chooser.setDialogTitle("Save reprojected shapefile");
chooser.setSaveFile(sourceFile);
int returnVal = chooser.showSaveDialog(null);
if (returnVal != JFileDataStoreChooser.APPROVE_OPTION) {
return;
}
File file = chooser.getSelectedFile();
if (file.equals(sourceFile)) {
JOptionPane.showMessageDialog(null, "Cannot replace " + file);
return;
}
// set up the math transform used to process the data
CoordinateReferenceSystem dataCRS = schema.getCoordinateReferenceSystem();
CoordinateReferenceSystem worldCRS = CRS.decode("EPSG:32056", true);// map.getCoordinateReferenceSystem();
boolean lenient = true; // allow for some error due to different datums
MathTransform transform = CRS.findMathTransform(dataCRS, worldCRS, lenient);
// grab all features
SimpleFeatureCollection featureCollection = featureSource.getFeatures();
// And create a new Shapefile with a slight modified schema
DataStoreFactorySpi factory = new ShapefileDataStoreFactory();
Map<String, Serializable> create = new HashMap<String, Serializable>();
create.put("url", file.toURI().toURL());
create.put("create spatial index", Boolean.TRUE);
DataStore dataStore = factory.createNewDataStore(create);
SimpleFeatureType featureType = SimpleFeatureTypeBuilder.retype(schema, worldCRS);
dataStore.createSchema(featureType);
String createdName = dataStore.getTypeNames()[0];
// carefully open an iterator and writer to process the results
Transaction transaction = new DefaultTransaction("Reproject");
FeatureWriter<SimpleFeatureType, SimpleFeature> writer = dataStore.getFeatureWriterAppend(createdName,
transaction);
SimpleFeatureIterator iterator = featureCollection.features();
try {
int counter = 0;
while (iterator.hasNext()) {
// copy the contents of each feature and transform the geometry
SimpleFeature feature = iterator.next();
SimpleFeature copy = writer.next();
org.locationtech.jts.geom.Geometry geometry = (org.locationtech.jts.geom.Geometry) feature
.getDefaultGeometry();
org.locationtech.jts.geom.Geometry geometry2 = JTS.transform(geometry, transform);
System.out.println(geometry.isSimple() && geometry2.isSimple());
// if (geometry2.isValid()) {
copy.setAttributes(feature.getAttributes());
counter++;
copy.setDefaultGeometry(geometry2);
writer.write();
// }
}
transaction.commit();
System.out.println("valid geometries : " + counter);
JOptionPane.showMessageDialog(null, "Export to shapefile complete");
} catch (Exception problem) {
problem.printStackTrace();
transaction.rollback();
JOptionPane.showMessageDialog(null, "Export to shapefile failed");
} finally {
writer.close();
iterator.close();
transaction.close();
}
}
// docs end export
// docs start validate
private int validateFeatureGeometry(ProgressListener progress) throws Exception {
final SimpleFeatureCollection featureCollection = featureSource.getFeatures();
// Rather than use an iterator, create a FeatureVisitor to check each
// fature
class ValidationVisitor implements FeatureVisitor {
public int numInvalidGeometries = 0;
public void visit(Feature f) {
SimpleFeature feature = (SimpleFeature) f;
Geometry geom = (Geometry) feature.getDefaultGeometry();
if (geom != null && !geom.isValid()) {
numInvalidGeometries++;
System.out.println("Invalid Geoemtry: " + feature.getID());
}
}
}
ValidationVisitor visitor = new ValidationVisitor();
// Pass visitor and the progress bar to feature collection
featureCollection.accepts(visitor, progress);
return visitor.numInvalidGeometries;
}
// docs end validate
// docs start export action
class ExportShapefileAction extends SafeAction {
ExportShapefileAction() {
super("Export...");
putValue(Action.SHORT_DESCRIPTION, "Export using current crs");
}
public void action(ActionEvent e) throws Throwable {
exportToShapefile();
}
}
// docs end export action
/**
* This class performs the task of checking that the Geometry of each
* feature is topologically valid and reports on the results. It also
* supplies the name and tool tip.
*/
// docs start validate action
class ValidateGeometryAction extends SafeAction {
ValidateGeometryAction() {
super("Validate geometry");
putValue(Action.SHORT_DESCRIPTION, "Check each geometry");
}
public void action(ActionEvent e) throws Throwable {
int numInvalid = validateFeatureGeometry(null);
String msg;
if (numInvalid == 0) {
msg = "All feature geometries are valid";
} else {
msg = "Invalid geometries: " + numInvalid;
}
JOptionPane.showMessageDialog(null, msg, "Geometry results", JOptionPane.INFORMATION_MESSAGE);
}
}
// docs end validate action
}
The output obtained after doing projection using Geotools are a lot different than what I used to get from ArcMap of esri. Is there any other transformation that I should perform.
When I try this (with v22.x) all I get is an error as too many points are outside the valid projection error. This is because you are taking a map of the world and reprojecting it to a CRS designed for Wyoming.
It seems that ESRI are being "helpful" and clipping your output to the area of validity (assuming you meant something other than EPSG:32056). GeoTools assumes that you know what you are doing and doesn't do that, which is why you have all the countries of the world shown in that map.
Here is the output for just the USA, which suggests that the ESRI image you show is a different projection again (look at the 49th parallel).

How to get a Flutter Uint8List from a Network Image?

I'm trying to convert a network image into a file and the first part of that is to convert it into a Uint8List. Here is how I'm doing this with 1 of my asset images...
final ByteData bytes = await rootBundle.load('assests/logo');
final Uint8List list = bytes.buffer.asUint8List();
final tempDir = await getTemporaryDirectory();
final file = await new File('${tempDir.path}/image.jpg').create();
file.writeAsBytesSync(list);
How can I do this with Image.network(imageUrl.com/image)
The simplest way seeems to get the http response using the image url and response.bodyBytes would contain the data in Uint8List.
http.Response response = await http.get(
'https://flutter.io/images/flutter-mark-square-100.png',
);
response.bodyBytes //Uint8List
Now you can do things like converting to base64 encoded string base64.encode(response.bodyBytes);
Update: With newer version of http, you need to add Uri.parse()
Eg.
http.Response response = await http.get(
Uri.parse('https://flutter.io/images/flutter-mark-square-100.png'),
);
I figured out a different solution. Hope it helps someone.
import 'dart:typed_data';
import 'package:flutter/services.dart';
Uint8List bytes = (await NetworkAssetBundle(Uri.parse(imageUrl))
.load(imageUrl))
.buffer
.asUint8List();
void initState() {
super.initState();
var sunImage = new NetworkImage(
"https://resources.ninghao.org/images/childhood-in-a-picture.jpg");
sunImage.obtainKey(new ImageConfiguration()).then((val) {
var load = sunImage.load(val);
load.addListener((listener, err) async {
setState(() => image = listener);
});
});
}
See also https://github.com/flutter/flutter/issues/23761#issuecomment-434606683
Then you can use image.toByteData().buffer.asUInt8List()
See also https://docs.flutter.io/flutter/dart-ui/Image/toByteData.html
The answers here are relevant and help explain how dart and flutter image compression/conversion works. If you would like a shortcut, there is this package https://pub.dev/packages/network_image_to_byte that makes it really easy.
After trying for hours this is what helped me
import 'dart:io';
import 'package:http/http.dart' as http;
import 'package:path/path.dart' as path;
import 'package:path_provider/path_provider.dart';
Future<File> getFileFromNetworkImage(String imageUrl) async {
var response = await http.get(imageUrl);
final documentDirectory = await getApplicationDocumentsDirectory();
String fileName = DateTime.now().millisecondsSinceEpoch.toString();
File file = File(path.join(documentDirectory.path, '$fileName.png'));
file.writeAsBytes(response.bodyBytes);
return file;
}
final file = await getFileFromNetworkImage("<your network image Url here>");
Note: this also converts mp4 videos to a File.
originally answered here
As http needs Uri this would be helpful:
you should remove the begining serverAddress from your ImageAddress first :
something like this in my case that I have 3001 in my url:
String serverAddress = 'myAddress.com:3001';
int indexOf3001 = imageAddress.indexOf('3001');
String trimmedImageAddress= imageAddress.substring(indexOf3001 + 4);
then :
var imageUrl = Uri.https(serverAddress, trimmedImageAddress);
final http.Response responseData = await http.get(imageUrl);
Uint8List imageBytes = responseData.bodyBytes;
this works on device and web too, hope it can help.

Resources