How to split a list into sublists using flutter? - flutter

I'm new with flutter.
I have data in txt file I retrieve it, then, I convert it into list and finally I split this list into sublists. Every sublist contains 19 values.
It's okey for this part. But now, the problem is that in the end of file we could have less than 19 values. So my question is how to add this values to another sublist also.
Actually, those sublists contains hexadecimals values, I was thinking about filling the last sublist with zeros until we have 19 values.But, I don't know how to do this.
Or, if you have any other solution to fix this issue?
this is my code:
static Future<List> localPath() async {
File textasset = File('/storage/emulated/0/RPSApp/assets/bluetooth.txt');
final text = await textasset.readAsString();
final bytes =
text.split(',').map((s) => s.trim()).map((s) => int.parse(s)).toList();
final chunks = [];
//final list4 = [];
int chunkSize = 19;
for (int i = 0; i < 40; i += chunkSize) {
chunks.add(bytes.sublist(
i, i + chunkSize > bytes.length ? bytes.length : i + chunkSize));
}
return chunks;
}
Thanks in advance for your help

import 'package:collection/collection.dart'; // add to your pubspec
final newList = originalList.slices(19).toList();
Done. Read the documentation for details.
Edit: After reading your comment, I came up with this:
import 'dart:math';
import 'package:collection/collection.dart';
void main(List<String> arguments) {
final random = Random();
const chunkSize = 7;
final source = List.generate(100, (index) => random.nextInt(100) + 1);
List<int> padTo(List<int> input, int count) {
return [...input, ...List.filled(count - input.length, 0)];
}
List<int> padToChunksize(List<int> input) => padTo(input, chunkSize);
final items = source.slices(chunkSize).map(padToChunksize).toList();
print(items);
}
which demonstrates how to pad each short list with more 0's.

Related

Dart Fails to save Bytes to PNG, JPEG

I have been trying for hours to figure out why my code is not working. Basically, I have an image. I load its bytes into dart as a list of Uint8List. Then, I replace the values of the list with some other values. The problem is that after replacing the values, when I call the File().writeAsBytes() function, the image is CORRUPTED. Don't know why this is happening. Tried doing everything I could.
var b = File("assets/1K91k (1).jpg").readAsBytesSync();
void main() {
runApp(const MyApp());
for (int i = 0; i < b.length; i++) {
double check = b[i] / 255;
if (check > 0.8) {
b[i] = 255;
} else {
b[i] = 2;
}
}
File("/home/kq1231/Desktop/test.jpg")
..createSync()
..writeAsBytesSync(b);
}
I tried converting the b list to a Uint8List but to no avail.
Feels funny to answer my own question but here's how it got working:
import 'package:image/image.dart' as image;
import 'dart:io';
image.Image prettify(String fileName, String exportPath, String imageName,
double threshold, int blurRadius) {
var b = image.decodeImage(File(fileName).readAsBytesSync());
b = image.gaussianBlur(b!, blurRadius);
for (int i = 0; i < b.width; i++) {
for (int j = 0; j < b.height; j++) {
var pix = b.getPixel(i, j);
if ((image.getBlue(pix) + image.getRed(pix) + image.getGreen(pix)) /
(255 * 3) >
threshold) {
b.setPixel(i, j, 0xffffff);
} else {
b.setPixel(i, j, 0);
}
}
}
File("$exportPath/$imageName")
..createSync()
..writeAsBytesSync(image.encodePng(b));
return b;
}
This is a function called prettify. It applies a specific operation to a given image. First, decode the image. Then, loop through each pixel, average the R, G and B values to get the grayscale value (get the value of the pixel using image.getPixel() and set its value using image.setPixel()). Then, encode it back to .png format and save it.
Note that image is the name of the library imported.

Generate 4 random numbers that add to a certain value in Dart

I want to make 4 numbers that add up to a certain number that is predefined.
For instance, I want four random numbers when added gives me 243.
Any type of way works as long as it works :)
this is more a math problem than a programming problem.
Maybe you can do something like this, if 0 is allowed.
var random = new Random();
final predefindedNumber = 243;
var rest = predefindedNumber;
final firstValue = random.nextInt(predefindedNumber);
rest -= firstValue;
final secondValue = rest <= 0 ? 0 : random.nextInt(rest);
rest -= secondValue;
final thirdValue = rest <= 0 ? 0 : random.nextInt(rest);
rest -= thirdValue;
final fourthValue = rest;
print("$fourthValue $secondValue $thirdValue $fourthValue");
With this implementation it´s possible to get somthing like this 243 0 0 0
This works:
import 'dart:math';
void main() {
int numberOfRandNb = 4;
List randomNumbers = [];
int predefinedNumber = 243;
for(int i = 0; i < numberOfRandNb - 1; i++) {
int randNb = Random().nextInt(predefinedNumber);
randomNumbers.add(randNb);
predefinedNumber -= randNb;
}
randomNumbers.add(predefinedNumber);
print(randomNumbers.join(' '));
}

Image to RGB matrix in flutter

I am a beginner in Flutter. I want to choose an image from my local and convert it into an RGB array. Can anybody please provide me with the code to do so correctly?
You can use this package - image
It provides image conversion and manipulation utility functions.
import 'package:image/image.dart' as Imagi;
Here's how to use it to obtain RGB matrix of a file from ImagePicker()-
final image = await ImagePicker().pickImage(source: ImageSource.gallery);
if (image == null) return;
final imageTemp = File(image.path);
controlImage = imageTemp;
Now here's a function for obtaining the RGB matrix -
List<List<int>> imgArray = [];
void readImage() async{
final bytes = await controlImage!.readAsBytes();
final decoder = Imagi.JpegDecoder();
final decodedImg = decoder.decodeImage(bytes);
final decodedBytes = decodedImg!.getBytes(format: Imagi.Format.rgb);
// print(decodedBytes);
print(decodedBytes.length);
// int loopLimit = decodedImg.width;
int loopLimit =1000;
for(int x = 0; x < loopLimit; x++) {
int red = decodedBytes[decodedImg.width*3 + x*3];
int green = decodedBytes[decodedImg.width*3 + x*3 + 1];
int blue = decodedBytes[decodedImg.width*3 + x*3 + 2];
imgArray.add([red, green, blue]);
}
print(imgArray);
}
The array imgArray will contain the RGB matrix

Calculate Average Color from a SVG Image (SvgPicture.network(""))

I try to calculate the average color from SVG format Image, but I don't know how can an SVG Image from the network convert to Unit8List, ImageProvider, or BitMap!
for any of these types that I say, I can calculate the average color with the below code :
(I use image package)
import 'package:image/image.dart' as imgPack;
//
Unit8List _myHunit8List = ...
imgPack.Image bitmap = imgPack.decodeImage(_myHunit8List );
int redBucket = 0;
int greenBucket = 0;
int blueBucket = 0;
int pixelCount = 0;
for (int y = 0; y < bitmap.height; y++) {
for (int x = 0; x < bitmap.width; x++) {
int c = bitmap.getPixel(x, y);
pixelCount++;
redBucket += img.getRed(c);
greenBucket += img.getGreen(c);
blueBucket += img.getBlue(c);
}
}
Color averageColor = Color.fromRGBO(redBucket ~/ pixelCount,
greenBucket ~/ pixelCount, blueBucket ~/ pixelCount, 1);
how can I an SVG Image from the network
( I use flutter_svg package like:
SvgPicture.network(url);
) convert to Unit8List ?
It transfers from Image url to Uint8List.
Future<Uint8List> getUint8ListFromImage(imgUrl) async {
Uint8List bytes = (await NetworkAssetBundle(Uri.parse(imgUrl)).load(imgUrl))
.buffer
.asUint8List();
print(bytes);
return bytes;
}
you can convert network image to file and then you can easily convert file to uint8List,
convert image url to file
Future<File> urlToFile(String imageUrl) async {
// generate random number.
var rng = new Random();
// get temporary directory of device.
Directory tempDir = await getTemporaryDirectory();
// get temporary path from temporary directory.
String tempPath = tempDir.path;
// create a new file in temporary path with random file name.
File file = new File('$tempPath'+ (rng.nextInt(100)).toString() +'.svg');
// call http.get method and pass imageUrl into it to get response.
http.Response response = await http.get(imageUrl);
// write bodyBytes received in response to file.
await file.writeAsBytes(response.bodyBytes);
// now return the file which is created with random name in
// temporary directory and image bytes from response is written to // that file.
return file;
}

How to generate random numbers without repetition in Flutter

I need to generate random numbers to use them as index and i need the generated number to be within a range and cannot be repeated. Is there a predefined function in Flutter to do that or am i going to create my own function?
you can use the Random class and then use a Set because unlike List you don't need to do any extra checking for duplication as Set itself won't allow any duplicated element.
for example:
Set<int> setOfInts = Set();
setOfInts.add(Random().nextInt(max));
I think you could simply create a simple shuffled list of index and use removeLast() on it each time you need a new value.
var randomPicker = List<int>.generate(n, (i) => i + 1)..shuffle();
...
int random1 = randomPicker.removeLast();
int random2 = randomPicker.removeLast();
assert(random1 != random2);
Where n is your maximum index.
Use random from math library:
import 'dart:math';
Random random = new Random();
int random_number = random.nextInt(100); // from 0 up to 99
And if you want to change minimum number you can use below trick, it will select from 10 up to 99:
int randomNumber = random.nextInt(90) + 10;
If you need multiple you can add those numbers to list and check them if there is exist with contain, such as:
List<int> numberList=[];
Random random = new Random();
for (var i = 0; i == 10; i++){
int random_number = random.nextInt(100);
if (!numberList.contains(random_number)) {numberList.add(random_number);}
}
I tried using all the codes above but none solved my problem.
I created this and it worked for me:
class Utils {
static final _random = Random();
static final Set<int> _setOfInts = {};
static int randomUnique({required limit}) {
debugPrint("limit: $limit ---> ${_setOfInts.length} ${_setOfInts.toString()}");
int randomInt = _random.nextInt(limit) + 1;
if (_setOfInts.contains(randomInt)) {
return randomUnique(limit: limit);
} else {
_setOfInts.add(randomInt);
return randomInt;
}
}
}