Skip to content

Commit

Permalink
feat: import of animated gif images
Browse files Browse the repository at this point in the history
  • Loading branch information
ZauberNerd committed Jan 5, 2025
1 parent a253b7d commit 261cedc
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 23 deletions.
61 changes: 38 additions & 23 deletions lib/bademagic_module/utils/file_helper.dart
Original file line number Diff line number Diff line change
Expand Up @@ -366,34 +366,49 @@ class FileHelper {
// Open file picker to select a JSON file
FilePickerResult? result = await FilePicker.platform.pickFiles(
type: FileType.custom,
allowedExtensions: ['json'], // Only allow JSON files
allowedExtensions: ['json', 'gif'],
);

if (result != null && result.files.isNotEmpty) {
// Get the selected file
File file = File(result.files.single.path!);
if (result == null || result.files.isEmpty) {
ToastUtils().showToast('No file selected');
return false;
}

// Read the content of the file
String jsonContent = await file.readAsString();
File file = File(result.files.single.path!);

// Parse the JSON data
Map<String, dynamic> importedBadge = jsonDecode(jsonContent);
logger.d('Imported badge: $importedBadge');
// Validate the structure of the JSON if necessary
if (importedBadge.containsKey('messages')) {
// Save the imported badge file to your application's directory
final directory = await getApplicationDocumentsDirectory();
final filePath = '${directory.path}/${result.files.single.name}';
logger.d('Importing badge to: $filePath');
File newFile = File(filePath);
await newFile.writeAsString(jsonContent);
return true;
} else {
throw Exception("Invalid Badge Data");
}
if (file.path.toLowerCase().endsWith('.gif')) {
final fileName = file.uri.pathSegments.last.replaceAll('.gif', '.json');

final hexFrames =
imageUtils.convertGifFramesToLEDHex(await file.readAsBytes());

Data data = Data.fromJson({
"messages": [
{
"text": hexFrames,
"flash": false,
"marquee": false,
"speed": "0x70",
"mode": "0x05"
}
],
});

await _writeToFile(fileName, jsonEncode(data.toJson()));

logger.d('Imported badge: $fileName, data: $data');

return true;
} else if (file.path.toLowerCase().endsWith('.json')) {
Data data = Data.fromJson(jsonDecode(await file.readAsString()));

await _writeToFile(result.files.single.name, jsonEncode(data.toJson()));

logger.d('Imported badge to: ${result.files.single.name}, data: $data');

return true;
} else {
ToastUtils().showToast('No file selected');
return false;
throw Exception('Only .gif and .json are supported!');
}
} catch (e) {
ScaffoldMessenger.of(context).showSnackBar(
Expand Down
33 changes: 33 additions & 0 deletions lib/bademagic_module/utils/image_utils.dart
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import 'dart:ui' as ui;
import 'dart:ui';

import 'package:badgemagic/bademagic_module/utils/converters.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:image/image.dart' as img;

class ImageUtils {
late double originalHeight;
Expand Down Expand Up @@ -223,4 +225,35 @@ class ImageUtils {
}
return Converters.convertBitmapToLEDHex(pixelArray, true);
}

List<String> convertGifFramesToLEDHex(Uint8List gifBytes) {
final gifImage = img.decodeGif(gifBytes);
if (gifImage == null) {
throw Exception('Failed to decode GIF');
}

List<String> hexFrames = [];

for (final frame in gifImage.frames) {
img.Image image = img.copyResize(frame, width: 48, height: 11);
image = img.grayscale(image);

List<List<int>> imageData = [];

for (int y = 0; y < image.height; y++) {
List<int> row = [];

for (int x = 0; x < image.width; x++) {
img.Pixel pixel = image.getPixel(x, y);
int value = img.getLuminance(pixel) > 128 ? 1 : 0;
row.add(value);
}
imageData.add(row);
}

hexFrames.addAll(Converters.convertBitmapToLEDHex(imageData, false));
}

return hexFrames;
}
}
24 changes: 24 additions & 0 deletions pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "7.1.0"
archive:
dependency: transitive
description:
name: archive
sha256: "6199c74e3db4fbfbd04f66d739e72fe11c8a8957d5f219f1f4482dbde6420b5a"
url: "https://pub.dev"
source: hosted
version: "4.0.2"
args:
dependency: transitive
description:
Expand Down Expand Up @@ -279,6 +287,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "4.0.2"
image:
dependency: "direct main"
description:
name: image
sha256: "8346ad4b5173924b5ddddab782fc7d8a6300178c8b1dc427775405a01701c4a6"
url: "https://pub.dev"
source: hosted
version: "4.5.2"
integration_test:
dependency: "direct dev"
description: flutter
Expand Down Expand Up @@ -476,6 +492,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.1.8"
posix:
dependency: transitive
description:
name: posix
sha256: a0117dc2167805aa9125b82eee515cc891819bac2f538c83646d355b16f58b9a
url: "https://pub.dev"
source: hosted
version: "6.0.1"
process:
dependency: transitive
description:
Expand Down
1 change: 1 addition & 0 deletions pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ dependencies:
file_picker: ^8.1.7
google_fonts: ^6.2.1
url_launcher: ^6.3.1
image: ^4.5.2

dev_dependencies:
flutter_test:
Expand Down

0 comments on commit 261cedc

Please sign in to comment.