Flutter : Save and Fetch ImageNetwork from API using SQFlite - flutter

I have problem with Insert and Fetch Image From API to local Directory.
So i have code to save image like this :
Save Image Code
Future saveImage(String imgUrl, String imgUrl2) async {
var response = await http.get("$baseURLimage/berita/$imgUrl");
var documentDirectory = await getApplicationDocumentsDirectory();
File file = File(join(documentDirectory.path, imgUrl2));
file.writeAsBytesSync(response.bodyBytes);
print(response);
print(response.bodyBytes);
print(documentDirectory);
print(file);
return file;
}
Button Code
void _saveImage() async {
var saveImage =
await api.saveImage(widget.gambarBerita, widget.gambarBerita);
print(saveImage);
}
In Console give me this :
I/flutter (23336): Instance of 'Response'
I/flutter (23336): [255, 216, 255, 224, 0, 16, 74, 70, 73, 70, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 255, 219, 0, 132, 0, 13, 13, 13, 13, 14, 13, 14, 16, 16, 14, 20, 22, 19, 22, 20, 30, 27, 25, 25, 27, 30, 45, 32, 34, 32, 34, 32, 45, 68, 42, 50, 42, 42, 50, 42, 68, 60, 73, 59, 55, 59, 73, 60, 108, 85, 75, 75, 85, 108, 125, 105, 99, 105, 125, 151, 135, 135, 151, 190, 181, 190, 249, 249, 255, 1, 13, 13, 13, 13, 14, 13, 14, 16, 16, 14, 20, 22, 19, 22, 20, 30, 27, 25, 25, 27, 30, 45, 32, 34, 32, 34, 32, 45, 68, 42, 50, 42, 42, 50, 42, 68, 60, 73, 59, 55, 59, 73, 60, 108, 85, 75, 75, 85, 108, 125, 105, 99, 105, 125, 151, 135, 135, 151, 190, 181, 190, 249, 249, 255, 255, 192, 0, 17, 8, 11, 244, 8, 88, 3, 1, 34, 0, 2, 17, 1, 3, 17, 1, 255, 196, 0, 156, 0, 0, 2, 3, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 4, 5, 3, 6, 7, 16, 0, 2, 2, 1, 4, 1, 3, 3, 2, 4, 5, 5, 0, 0, 1, 13, 0, 1, 2, 3, 17, 4, 18, 33, 49, 5, 19, 65, 81, 34, 50, 97, 20, 113, 6, 35, 66, 82, 21, 51, 129, 145, 161, 36, 52, 98, 114, 177, 67, 83, 37, 53, 115, 22, 68, 99, 193, 8
I/flutter (23336): Directory: '/data/user/0/com.example.flutter_news/app_flutter'
I/flutter (23336): File: '/data/user/0/com.example.flutter_news/app_flutter/92dae9b51087d930a32aff53eaded163.jpg'
I/flutter (23336): File: '/data/user/0/com.example.flutter_news/app_flutter/92dae9b51087d930a32aff53eaded163.jpg'
But my images still not saved in my device.
can you help me ?

You can use package https://pub.dev/packages/network_to_file_image
In demo, it download image and show it, so you can see success or not directly
From official introduction
This is a mixture of FileImage and NetworkImage. It will download the image from the url once, save it locally in the file system, and then use it from there in the future.
full example code
import 'dart:async';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:network_to_file_image/network_to_file_image.dart';
import 'package:path/path.dart' as p;
import 'package:path_provider/path_provider.dart';
String flutterLogoUrl =
"https://upload.wikimedia.org/wikipedia/commons/1/17/Google-flutter-logo.png";
String flutterLogoFileName = "flutter.png";
void main() async {
runApp(
MaterialApp(
home: Demo(
url: flutterLogoUrl,
file: await file(flutterLogoFileName),
),
),
);
}
Future<File> file(String filename) async {
Directory dir = await getApplicationDocumentsDirectory();
String pathName = p.join(dir.path, filename);
return File(pathName);
}
class Demo extends StatelessWidget {
final String url;
final File file;
const Demo({Key key, this.url, this.file}) : super(key: key);
#override
Widget build(BuildContext context) => Scaffold(
appBar: AppBar(title: const Text('Network to file image example')),
body: Padding(
padding: const EdgeInsets.all(30.0),
child: Image(image: NetworkToFileImage(url: url, file: file, debug: true)),
),
);
}
In demo picture, you can see it print image url and saved file path

Related

decode base64url as uint8array

I'm trying to turn a string of a JWT token signature into a uint8array.
lX_aBSgGVYWd2FL6elRHoPJ2nab0IkmmX600cwZPCyK_SazZ-pzBUGDDQ0clthPVAtoS7roHg14xpEJlcSJUZBA7VTlPiDCOrkie_Hmulj765qS44t3kxAYduLhNQ-VN
The expected outcome should be the following with the size of 96 (base64url encoding)
[149, 127, 218, 5, 40, 6, 85, 133, 157, 216, 82, 250, 122, 84, 71, 160, 242, 118, 157, 166, 244, 34, 73, 166, 95, 173, 52, 115, 6, 79, 11, 34, 191, 73, 172, 217, 250, 156, 193, 80, 96, 195, 67, 71, 37, 182, 19, 213, 2, 218, 18, 238, 186, 7, 131, 94, 49, 164, 66, 101, 113, 34, 84, 100, 16, 59, 85, 57, 79, 136, 48, 142, 174, 72, 158, 252, 121, 174, 150, 62, 250, 230, 164, 184, 226, 221, 228, 196, 6, 29, 184, 184, 77, 67, 229, 77]
But I coudn't reverse engineer this I kept getting a size of 64 instead
[103, 10, 34, 6, 104, 125, 101, 234, 5, 23, 143, 198, 138, 228, 164, 134, 170, 116, 240, 159, 82, 223, 58, 73, 9, 49, 70, 51, 52, 229, 241, 5, 45, 146, 219, 135, 53, 177, 148, 181, 210, 164, 145, 59, 99, 95, 35, 46, 212, 62, 247, 142, 115, 234, 186, 88, 173, 148, 16, 157, 235, 29, 62, 93
Here's my function that was originally used for base16 and I'm now try to modify this to work for base64url
const convert = (str) => {
const segmented = str.match(/.{1,2}/g);
const arr = segmented.map((segment, i) => {
const powers = [16,1];
const alphabets = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
const two_bits = segment.split('');
const result_arr = two_bits.map((hex, i) => {
const decimal = alphabets.indexOf(hex);
const sum_of_power = powers[i] * decimal;
return sum_of_power;
});
const result = result.reduce((a, b) => a + b);
return result;
});
return new Uint8Array(arr);
};
Any help would be appreciated!
Here's the base64url decode code, taken from my jose universal javascript module which I suggest you use for any and all JOSE functionality instead of writing your own.
const decodeBase64 = (encoded) => {
return new Uint8Array(atob(encoded)
.split('')
.map((c) => c.charCodeAt(0)));
};
const decode = (input) => {
try {
return decodeBase64(input.replace(/-/g, '+').replace(/_/g, '/').replace(/\s/g, ''));
}
catch (_a) {
throw new TypeError('The input to be decoded is not correctly encoded.');
}
};
decode('lX_aBSgGVYWd2FL6elRHoPJ2nab0IkmmX600cwZPCyK_SazZ-pzBUGDDQ0clthPVAtoS7roHg14xpEJlcSJUZBA7VTlPiDCOrkie_Hmulj765qS44t3kxAYduLhNQ-VN')

converting binary data to audio in flutter

I have my server in C# (windows forms) from which I record the sound of the system and send the sound as byte array segment through websocket. I created the client is in flutter to play the data received from the websocket sever,
when I print the data received from the server, it gives me something like this
[44, 208, 240, 11, 78, 112, 62, 234, 159, 35, 145, 128, 240, 99, 91,
123, 252, 181, 56, 44, 222, 214, 137, 206, 45, 55, 59, 114, 199, 206,
47, 230, 77, 154, 200, 12, 218, 187, 187, 100, 219, 225, 6, 82, 123,
75, 133, 251, 105, 44, 243, 232, 69, 24, 31, 95, 39, 136, 43, 152,
121, 233, 56, 22, 197, 141, 44, 213, 47, 182, 77, 59, 171, 201, 37,
101, 125, 203, 126, 113, 131, 175, 194, 244, 7, 158, 154, 138, 25,
223, 217, 123, 112, 225, 133, 139, 59, 230, 31, 227, 110, 92, 4, 187,
187, 99, 222, 217, 173, 153, 185, 54, 145, 63, 128, 102, 34, 148, 64,
242, 188, 131, 4, 127, 49, 217, 38, 41, 58, 39, 53, 209, 46, 216, 160,
164, 142, 102, 226, 151, 223, 133, 150, 201, 66, 131, 133, 89, 216,
69, 174, 181, 117, 114, 23, 188, 73, 1, 180, 156, 179, 254, 119, 219,
231, 142, 139, 40, 214, 75, 187, 97, 126, 85, 2, 86, 178, 7, 33, 112,
4, 121, 242, 39, 185, 155, 27, 173, 24, 185, 226, 167, 141, 105, 58,
104, 202, 47]
and when I print the runtime type of the data the result is
_uint8arrayView
I have surf the net found nothing in similar to my case in flutter so I don't know what to do again. I want to use soundpool package or AssetAudioPlayer package to play it. Any ideas will be well appreciated. Thanks in advance!.
Here is the main logic of what I have done so far in flutter
Future client() async {
Random r = new Random();
String key = base64.encode(List<int>.generate(8, (_) => r.nextInt(255)));
HttpClient client = HttpClient(/* optional security context here */);
Uri uri = new Uri(
scheme: "http",
host: _controller.text.trim(),
port: int.parse("5970", radix: 10),
path: "");
HttpClientRequest request = await client.getUrl(uri);
// HttpClientRequest request = await client.get(
// 'ws://${_controller.text.trim()}',
// int.parse("5970", radix: 10),
// 'chat'); // form the correct url here
request.headers.add('Connection', 'upgrade');
request.headers.add('Upgrade', 'websocket');
request.headers
.add('sec-websocket-version', '13'); // insert the correct version here
request.headers.add('sec-websocket-key', key);
HttpClientResponse response = await request.close();
// todo check the status code, key etc
Socket socket = await response.detachSocket();
WebSocket ws = WebSocket.fromUpgradedSocket(
socket,
serverSide: false,
);
ws.listen(
(event) {
connected = true;
var bytes = File.fromRawPath(event);
var s = openBytesStream(event);
//streamController.addStream(event);
//stream(s);
print(event.runtimeType);
//soudpool();
},
onError: (error) {
connected = false;
},
onDone: () {
connected = false;
},
cancelOnError: false,
);
}
final assetsAudioPlayer = AssetsAudioPlayer();
Future stream(String url) async {
try {
await assetsAudioPlayer.open(
Audio.liveStream(url),
showNotification: true,
autoStart: true,
);
} catch (t) {
//stream unreachable
print(t);
}
}
Future<void> soudpool(Uint8List soundData) async {
Soundpool pool = Soundpool(streamType: StreamType.notification);
int soundId = await pool.loadAndPlayUint8List(soundData);
int streamId = await pool.play(soundId);
}

Flutter Archive Plugin returns data in Uint8List format of my XML file

Flutter Archive Plugin returns data in Uint8List format of my XML file. How can i convert the List data into String so that i can parse the XML in the app
Here is the piece of code i wrote
unarchiveAndSave(var zippedFile,String filepath) async {
// String _dir = (await
getApplicationSupportDirectory()).path+"/SampleFolder";
List<int> bytes = await zippedFile.readAsBytesSync();
if (bytes != null) {
print("FILE FOUND: $_path");
}
else {
print("ERROR NO FILE FOUND: $_path");
return null;
}
Archive archive = new ZipDecoder().decodeBytes(bytes);
for (ArchiveFile file in archive) {
String filename = file.name;
Uint8List fileContent = file.content;
print("File Content ::: $fileContent");
if (file.isFile) {
List<int> data = file.content;
print(data);
/*File contentFile = new File('$filepath/'+filename)
..createSync(recursive: true)
..writeAsBytesSync(bytes);*/
}
else {
new Directory('$filepath/'+filename)
..create(recursive: true);
print('Created and written $filepath/$filename');
}
}
}
here is the data i'm getting
[45, 246, 8, 26, 241, 251, 150, 86, 156, 194, 16, 162, 231, 138, 40, 95, 178, 209, 62, 79, 136, 196, 26, 234, 97, 105, 44, 50, 93, 141, 26, 111, 253, 199, 19, 255, 250, 57, 105, 27, 114, 86, 164, 144, 98, 101, 84, 114, 192, 236, 19, 187, 225, 186, 188, 91, 152, 187, 20, 228, 69, 23, 219, 34, 51, 85, 241, 124, 230, 224, 36, 7, 56, 5, 235, 172, 34, 199, 63, 108, 69, 239, 161, 52, 11, 56, 138, 246, 57, 218, 93, 147, 89, 85, 252, 26, 45, 117, 76, 50, 73, 76, 170, 38, 91, 122, 97, 151, 175, 57, 135, 30, 30, 115, 224, 106, 4, 86, 164, 118, 190, 48, 118, 211, 104, 194, 96, 229, 57, 173, 22, 230, 143, 217, 204, 82, 177, 201, 224, 121, 136, 47, 147, 217, 217, 111, 60, 143, 133, 79, 162, 255, 71, 127, 162, 155, 20, 43, 144, 5, 116, 215, 179, 97, 7, 193, 24, 234, 193, 235, 181, 115, 193, 150, 29, 83, 232, 48, 8, 4, 84, 214, 255, 177, 230, 99, 64, 19, 39, 78, 127, 59, 1, 138, 158, 152, 104, 235, 216, 69, 68, 133, 23, 15, 99, 162, 29, 127, 253, 56, 180, 231, 32, 77, 93, 188, 2, 152, 248, 157, 46, 47, 72, 161, 153, 168, 8
package:archive is a pure Dart package to handle zip and gzip compression. If you know that the zip file contains UTF-8 encoded text files you can decompress each file in memory and then convert the decompressed contents to characters using a character codec - presumably the UTF-8 one, especially as this is the most frequent character encoding of XML.
As the package is pure Dart you can use it from a pure Dart program, which may be easier to test than on your phone. (Incidentally, also included in the package is the dart:io based version, which may be more efficient than the pure Dart version as long as you aren't targetting the web.)
Here's a working snippet that reads a zip file containing text files, prints the file names and the first few characters of each file.
import 'dart:convert';
import 'dart:io';
import 'package:archive/archive.dart';
void main() async {
var zipBytes = await File('zip1.zip').readAsBytes();
Archive archive = ZipDecoder().decodeBytes(zipBytes);
for (var archiveFile in archive) {
print(archiveFile.name);
var content = archiveFile.content;
print(utf8.decode(content).substring(0, 10));
}
}

Elixir stream audio to users

The following code streams a file to a process.
I want to stream audio/mp3
to many users who will hear it via html5 audio tag.
How can it be done via File.stream!?
defmodule Test do
def start do
p = spawn(Test, :say, [])
send p, {self, "a message"}
end
def say do
receive do
{from, msg} ->
IO.puts "Process #{inspect self} says: #{msg}"
stream_bytes = 128
File.stream!("./song.mp3", [], stream_bytes)
|> Enum.each(fn chunk ->
IO.inspect chunk
end)
say
end
end
end
$: iex test.ex
iex(1)> Test.start
output:
<<171, 46, 254, 26, 163, 32, 178, 27, 0, 75, 17, 35, 4, 236, 51, 57, 5, 144, 154, 198, 166, 47, 62, 4, 61, 85, 67, 135, 16, 34, 82, 49, 57, 176, 131, 96, 116, 152, 232, 24, 32, 140, 220, 67, 73, 128, 165, 178, 230, 202, ...>>
<<100, 220, 156, 191, 38, 0, 161, 117, 80, 16, 102, 91, 22, 5, 8, 66, 26, 7, 193, 155, 193, 66, 198, 28, 157, 244, 65, 131, 204, 240, 5, 172, 143, 44, 173, 85, 144, 2, 157, 144, 145, 97, 200, 236, 16, 49, 149, 150, 133, 67, ...>>
<<150, 54, 37, 254, 192, 218, 218, 26, 69, 231, 88, 124, 33, 129, 169, 66, 117, 52, 214, 134, 130, 103, 85, 130, 48, 6, 144, 221, 153, 132, 8, 181, 26, 27, 83, 140, 54, 117, 149, 7, 60, 144, 237, 248, 132, 12, 210, 51, 103, 116, ...>>
<<57, 2, 143, 220, 198, 182, 22, 177, 231, 126, 187, 147, 33, 9, 1, 5, 164, 2, 36, 105, 47, 255, 255, 255, 255, 255, 245, 54, 51, 225, 104, 98, 1, 184, 148, 206, 50, 135, 230, 28, 50, 47, 144, 134, 53, 16, 64, 130, 192, 198, ...>>
..............
how can I use JavaScript to read this binary data and hear it via audio tag ?
If you're using a plug based web framework it should be reasonably straight forward. This is possible if you're using plug directly or if you're using it from within phoenix (which is based on plug).
Maybe a plug like this would do the trick
defmodule Audio do
#chunk_size 128
def init(opts), do: opts
def song(conn, _opts) do
conn = conn
|> send_chunked(200)
|> put_resp_header("content-type", "audio/mpeg")
File.stream!("/some/song/somewhere.mp3", [], #chunk_size)
|> Enum.into(conn)
end
end
Maybe you want to hook up your plug to a phoenix router like this
defmodule MyApp.Router do
use MyApp.Web, :router
get "/the_song", Audio, :song
end
Then in your page
<audio src="/the_song">
Your browser does not support the <code>audio</code> element.
</audio>

IPython interactive shell output formatting configuration

If there's a quick fix for this, apologies in advance. In the IPython shell, if I have this:
In [1]: x = [i for i in range(100)]
then I get a list printed with each element on a new line if I call it:
In [2]: x
Out[2]: [0
1,
2,
and so on down to 100. Irritating as hell because often I'm calling objects and don't know how long they'll be (and don't want to check beforehand, and don't want my last commands to get pushed up and out of the way). How can I get it to print that result the way it would in regular python? I.e.:
>>> x
[1,2,3,4,5,6,7,8,....
9,10,11, ..... 100]
What you want is to disable pretty print.
$ ipython --help
[...]
--no-pprint
Disable auto auto pretty printing of results.
[...]
Which gives :
$ ipython --no-pprint
[...]
In [1]: x = [i for i in range(100)]
In [2]: x
Out[2]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99]