Skip to content

Instantly share code, notes, and snippets.

@AmirArani
Last active July 15, 2024 04:15
Show Gist options
  • Save AmirArani/b19d13be3f2c34de9196ae9495cb2b93 to your computer and use it in GitHub Desktop.
Save AmirArani/b19d13be3f2c34de9196ae9495cb2b93 to your computer and use it in GitHub Desktop.
Extract BMP file "ColorTable" w/ Dart🎯
import 'dart:typed_data';
import 'package:file_picker/file_picker.dart';
import 'package:flutter/material.dart';
import 'package:image/image.dart' as img;
class ColorTableData {
final List<ColorTableListItem> colorTableList;
final int totalPixelCount;
ColorTableData({
required this.colorTableList,
required this.totalPixelCount,
});
}
class ColorTableListItem {
final Color color;
final int count;
ColorTableListItem({required this.color, required this.count});
}
class ColorTableExtractTestScreen extends StatefulWidget {
const ColorTableExtractTestScreen({super.key});
@override
State<ColorTableExtractTestScreen> createState() => _ColorTableExtractTestScreenState();
}
class _ColorTableExtractTestScreenState extends State<ColorTableExtractTestScreen> {
ColorTableData colorTable = ColorTableData(totalPixelCount: 0, colorTableList: []);
@override
Widget build(BuildContext context) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () async {
/// pick file
PlatformFile imageFile = await pickImage();
/// convert file to bmpImage
img.Image? bmpImage = convertFileToBmpImage(imageFile);
/// extract color table of bmpImage
List<Color> colorTableListItemColors =
extractColorTableColors(palette: bmpImage?.palette);
/// calculate pixel count of each color of color table
List<int> colorTableListItemPixelCount = calculateColorTableColorPixelCount(
bmpImage: bmpImage!, colorTableList: colorTableListItemColors);
/// bind each color count to each color value and make a list of them.
List<ColorTableListItem> colorTableList = colorTableListGenerator(
colorTableListItemColors,
colorTableListItemPixelCount,
);
/// create ColorTableData model.
colorTable = ColorTableData(
colorTableList: colorTableList,
totalPixelCount: calculateTotalPixelCount(bmpImage: bmpImage),
);
setState(() {
colorTable;
});
},
child: const Text('Pick and Extract Color Table'),
),
const SizedBox(height: 40),
const Text('Extracted ColorTable',
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
const SizedBox(height: 10),
Wrap(
spacing: 10,
children: colorTable.colorTableList.map((ColorTableListItem colorTableItem) {
return Column(
children: [
Container(
width: 30,
height: 30,
color: colorTableItem.color,
),
Text('Count: ${colorTableItem.count}'),
Text('Percent${colorTableItem.count / colorTable.totalPixelCount}'),
],
);
}).toList(),
),
],
),
);
}
}
Future<PlatformFile> pickImage() async {
FilePickerResult? result = await FilePicker.platform.pickFiles(
type: FileType.image,
withData: true,
allowedExtensions: ['bmp'],
);
if (result != null) {
PlatformFile file = result.files.first;
return file;
} else {
// Handle the case where file.bytes is null
throw Exception('File is null!!!');
}
}
img.Image? convertFileToBmpImage(PlatformFile file) {
if (file.bytes != null) {
Uint8List fileBytes = file.bytes!;
img.Image? bmpImage = img.decodeBmp(fileBytes);
return bmpImage;
} else {
throw Exception('File byte is null!!!');
}
}
List<Color> extractColorTableColors({required img.Palette? palette}) {
List<Color> colorTable = [];
for (int i = 0; i < palette!.numColors; i++) {
num r = palette.getRed(i);
num g = palette.getGreen(i);
num b = palette.getBlue(i);
num a = palette.getAlpha(i);
Color color = Color.fromARGB(a as int, r as int, g as int, b as int);
colorTable.add(color);
}
return colorTable;
}
List<int> calculateColorTableColorPixelCount(
{required img.Image bmpImage, required List<Color> colorTableList}) {
final List<int> colorsCount = List<int>.filled(colorTableList.length, 0);
for (int y = 0; y < bmpImage.height; y++) {
for (int x = 0; x < bmpImage.width; x++) {
for (int z = 0; z < colorTableList.length; z++) {
var pixel = bmpImage.getPixel(x, y).toList();
if (pixel[0] == colorTableList[z].red &&
pixel[1] == colorTableList[z].green &&
pixel[2] == colorTableList[z].blue) {
colorsCount[z]++;
break;
}
}
}
}
return colorsCount;
}
List<ColorTableListItem> colorTableListGenerator(List<Color> colors, List<int> counts) {
List<ColorTableListItem> colorTableList = [];
if (colors.length == counts.length) {
for (int i = 0; i < colors.length; i++) {
colorTableList.add(
ColorTableListItem(
color: colors[i],
count: counts[i],
),
);
}
return colorTableList;
} else {
throw Exception('Length of ColorTable and Counts are not Same!!!');
}
}
int calculateTotalPixelCount({required img.Image bmpImage}) => bmpImage.width * bmpImage.height;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment