Skip to content

Commit

Permalink
feat: Added the logic for converting the SVG to led hex inorder to di…
Browse files Browse the repository at this point in the history
…splay the clipart to the badge.
  • Loading branch information
Jhalakupadhyay committed Jun 22, 2024
1 parent 2011bb5 commit c80258f
Show file tree
Hide file tree
Showing 4 changed files with 333 additions and 1 deletion.
103 changes: 103 additions & 0 deletions lib/bademagic_module/utils/converters.dart
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,107 @@ class Converters {
logger.d("message to hex = $message");
return messages;
}

//function to convert the bitmap to the LED hex format
//it takes the 2D list of pixels and converts it to the LED hex format
static List<String> convertBitmapToLEDHex(List<List<int>> image) {
// Determine the height and width of the image
int height = image.length;
int width = image.isNotEmpty ? image[0].length : 0;

// Initialize variables to calculate padding and offsets
int finalSum = 0;

// Calculate and adjust for right-side padding
for (int j = 0; j < width; j++) {
int sum = 0;
for (int i = 0; i < height; i++) {
sum += image[i][j]; // Sum up pixel values in each column
}
if (sum == 0) {
// If column sum is zero, mark all pixels in that column as -1
for (int i = 0; i < height; i++) {
image[i][j] = -1;
}
} else {
// Otherwise, update finalSum and exit loop
finalSum += j;
break;
}
}

// Calculate and adjust for left-side padding
for (int j = width - 1; j >= 0; j--) {
int sum = 0;
for (int i = 0; i < height; i++) {
sum += image[i]
[j]; // Sum up pixel values in each column (from right to left)
}
if (sum == 0) {
// If column sum is zero, mark all pixels in that column as -1
for (int i = 0; i < height; i++) {
image[i][j] = -1;
}
} else {
// Otherwise, update finalSum and exit loop
finalSum += (height - j - 1);
break;
}
}

// Calculate padding difference to align height to a multiple of 8
int diff = 0;
if ((height - finalSum) % 8 > 0) {
diff = 8 - (height - finalSum) % 8;
}

// Calculate left and right offsets for padding
int rOff = (diff / 2).floor();
int lOff = (diff / 2).ceil();

// Initialize a new list to accommodate the padded image
List<List<int>> list =
List.generate(height, (i) => List.filled(width + rOff + lOff, 0));

// Fill the new list with the padded image data
for (int i = 0; i < height; i++) {
int k = 0;
for (int j = 0; j < rOff; j++) {
list[i][k++] = 0; // Fill right-side padding
}
for (int j = 0; j < width; j++) {
if (image[i][j] != -1) {
list[i][k++] = image[i][j]; // Copy non-padded pixels
}
}
for (int j = 0; j < lOff; j++) {
list[i][k++] = 0; // Fill left-side padding
}
}

// Convert each 8-bit segment into hexadecimal strings
List<String> allHexs = [];
for (int i = 0; i < list[0].length ~/ 8; i++) {
StringBuffer lineHex = StringBuffer();

for (int k = 0; k < height; k++) {
StringBuffer stBuilder = StringBuffer();

// Construct 8-bit segments for each row
for (int j = i * 8; j < i * 8 + 8; j++) {
stBuilder.write(list[k][j]);
}

// Convert binary string to hexadecimal
String hex = int.parse(stBuilder.toString(), radix: 2)
.toRadixString(16)
.padLeft(2, '0');
lineHex.write(hex); // Append hexadecimal to line
}

allHexs.add(lineHex.toString()); // Store completed hexadecimal line
}

return allHexs; // Return list of hexadecimal strings
}
}
156 changes: 156 additions & 0 deletions lib/bademagic_module/utils/image_utils.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
import 'dart:ui' as ui;
import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_svg/flutter_svg.dart';

class ImageUtils {
// Define target width and height for the bitmap
static double targetHeight = 11.0;
static double targetWidth = 44.0;

//function to load and scale the svg according to the badge size
Future<ui.Image> scaleSVG(String svg) async {
//loading the Svg from the assets
String svgString = await rootBundle.loadString(svg);

// Load SVG picture and information
final SvgStringLoader svgStringLoader = SvgStringLoader(svgString);
final PictureInfo pictureInfo = await vg.loadPicture(svgStringLoader, null);
final ui.Picture picture = pictureInfo.picture;

//creating canvas to draw the svg on
final ui.PictureRecorder recorder = ui.PictureRecorder();
final ui.Canvas canvas = Canvas(recorder,
Rect.fromPoints(Offset.zero, Offset(targetWidth, targetHeight)));

//scaling the svg to the badge size
canvas.scale(targetWidth / pictureInfo.size.width,
targetHeight / pictureInfo.size.height);

//drawing the svg on the canvas
canvas.drawPicture(picture);

//converting the canvas to the ui.Image object
final ui.Image imgByteData = await recorder
.endRecording()
.toImage(targetWidth.ceil(), targetHeight.ceil());

return imgByteData;
}

//function to convert the ui.Image to byte array
Future<Uint8List?> convertImageToByteArray(ui.Image image) async {
final ByteData? byteData =
await image.toByteData(format: ui.ImageByteFormat.rawRgba);
return byteData?.buffer.asUint8List();
}

//function to convert the byte array to 2D list of pixels
List<List<int>> convertUint8ListTo2DList(
Uint8List byteArray, int width, int height) {
//initialize the 2D list of pixels
List<List<int>> pixelArray =
List.generate(height, (i) => List<int>.filled(width, 0));
int bytesPerPixel = 4; // RGBA format (4 bytes per pixel)
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
int index = (y * width + x) * bytesPerPixel;
if (index + bytesPerPixel <= byteArray.length) {
int r = byteArray[index];
int g = byteArray[index + 1];
int b = byteArray[index + 2];
int a = byteArray[index + 3];
int color = (a << 24) | (r << 16) | (g << 8) | b;
pixelArray[y][x] = color;
} else {
// Handle out-of-bounds case gracefully, e.g., fill with a default color
pixelArray[y][x] = Colors.transparent.value;
}
}
}
return pixelArray;
}

//function to trim the bitmap with the transparent pixels
//it iterates throught the 2D list of pixels and finds the bounding box of the non-transparent pixels
//and crops the bitmap to that bounding box
//it returns the cropped bitmap
List<List<int>> trimedBitmap(List<List<int>> source) {
int width = source[0].length;
int height = source.length;

int firstX = 0;
int firstY = 0;
int lastX = width;
int lastY = height;

bool found = false;

// Find firstX
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
if (source[y][x] != 0) {
firstX = x > 1 ? x - 1 : x;
found = true;
break;
}
}
if (found) break;
}

found = false;

// Find firstY
for (int y = 0; y < height; y++) {
for (int x = firstX; x < width; x++) {
if (source[y][x] != 0) {
firstY = y > 1 ? y - 1 : y;
found = true;
break;
}
}
if (found) break;
}

found = false;

// Find lastX
for (int x = width - 1; x >= firstX; x--) {
for (int y = height - 1; y >= firstY; y--) {
if (source[y][x] != 0) {
lastX = x < width - 2 ? x + 2 : x + 1;
found = true;
break;
}
}
if (found) break;
}

found = false;

// Find lastY
for (int y = height - 1; y >= firstY; y--) {
for (int x = width - 1; x >= firstX; x--) {
if (source[y][x] != 0) {
lastY = y < height - 2 ? y + 2 : y + 1;
found = true;
break;
}
}
if (found) break;
}

// Create trimmed bitmap
List<List<int>> trimmedBitmap = List.generate(
lastY - firstY, (_) => List<int>.filled(lastX - firstX, 0));
for (int y = firstY; y < lastY; y++) {
for (int x = firstX; x < lastX; x++) {
trimmedBitmap[y - firstY][x - firstX] = source[y][x];
}
}

// Scale the bitmap to the desired dimension
return trimmedBitmap;
}
}
74 changes: 73 additions & 1 deletion pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "3.0.2"
flutter_svg:
dependency: "direct main"
description:
name: flutter_svg
sha256: "7b4ca6cf3304575fe9c8ec64813c8d02ee41d2afe60bcfe0678bcb5375d596a2"
url: "https://pub.dev"
source: hosted
version: "2.0.10+1"
flutter_test:
dependency: "direct dev"
description: flutter
Expand All @@ -160,6 +168,22 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.1.2"
http:
dependency: transitive
description:
name: http
sha256: "761a297c042deedc1ffbb156d6e2af13886bb305c2a343a4d972504cd67dd938"
url: "https://pub.dev"
source: hosted
version: "1.2.1"
http_parser:
dependency: transitive
description:
name: http_parser
sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b"
url: "https://pub.dev"
source: hosted
version: "4.0.2"
leak_tracker:
dependency: transitive
description:
Expand Down Expand Up @@ -248,6 +272,22 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.9.0"
path_parsing:
dependency: transitive
description:
name: path_parsing
sha256: e3e67b1629e6f7e8100b367d3db6ba6af4b1f0bb80f64db18ef1fbabd2fa9ccf
url: "https://pub.dev"
source: hosted
version: "1.0.1"
petitparser:
dependency: transitive
description:
name: petitparser
sha256: c15605cd28af66339f8eb6fbe0e541bfe2d1b72d5825efc6598f3e0a31b9ad27
url: "https://pub.dev"
source: hosted
version: "6.0.2"
provider:
dependency: "direct main"
description:
Expand Down Expand Up @@ -325,6 +365,30 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.3.2"
vector_graphics:
dependency: transitive
description:
name: vector_graphics
sha256: "32c3c684e02f9bc0afb0ae0aa653337a2fe022e8ab064bcd7ffda27a74e288e3"
url: "https://pub.dev"
source: hosted
version: "1.1.11+1"
vector_graphics_codec:
dependency: transitive
description:
name: vector_graphics_codec
sha256: c86987475f162fadff579e7320c7ddda04cd2fdeffbe1129227a85d9ac9e03da
url: "https://pub.dev"
source: hosted
version: "1.1.11+1"
vector_graphics_compiler:
dependency: transitive
description:
name: vector_graphics_compiler
sha256: "12faff3f73b1741a36ca7e31b292ddeb629af819ca9efe9953b70bd63fc8cd81"
url: "https://pub.dev"
source: hosted
version: "1.1.11+1"
vector_math:
dependency: transitive
description:
Expand Down Expand Up @@ -357,6 +421,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.5.1"
xml:
dependency: transitive
description:
name: xml
sha256: b015a8ad1c488f66851d762d3090a21c600e479dc75e68328c52774040cf9226
url: "https://pub.dev"
source: hosted
version: "6.5.0"
yaml:
dependency: transitive
description:
Expand All @@ -367,4 +439,4 @@ packages:
version: "3.1.2"
sdks:
dart: ">=3.3.4 <4.0.0"
flutter: ">=2.5.0"
flutter: ">=3.7.0-0"
1 change: 1 addition & 0 deletions pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ dependencies:
flutter_blue_plus: ^1.32.7
fluttertoast: ^8.2.6
logger: ^2.3.0
flutter_svg: ^2.0.10+1

dev_dependencies:
flutter_test:
Expand Down

0 comments on commit c80258f

Please sign in to comment.