69 lines
1.9 KiB
Dart
69 lines
1.9 KiB
Dart
import 'dart:io';
|
|
import 'dart:typed_data';
|
|
|
|
import 'package:image/image.dart' as img;
|
|
import 'package:injectable/injectable.dart';
|
|
|
|
import 'image_resizer.dart';
|
|
|
|
@singleton
|
|
class LvglImageConverter {
|
|
final ImageResizer _imageResizer;
|
|
|
|
LvglImageConverter(this._imageResizer);
|
|
static const int _magic = 0x19;
|
|
static const int _colorFormatRgb565 = 0x12;
|
|
static const int _flags = 0x00;
|
|
|
|
int _toRgb565(int r, int g, int b) {
|
|
return ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3);
|
|
}
|
|
|
|
Future<void> convertPngToBin(String imagePath, String binPath) async {
|
|
final imageFile = File(imagePath);
|
|
if (!await imageFile.exists()) {
|
|
throw FileSystemException('Image file not found', imagePath);
|
|
}
|
|
|
|
final bytes = await imageFile.readAsBytes();
|
|
var image = img.decodeImage(bytes);
|
|
if (image == null) {
|
|
throw FormatException('Failed to decode image: $imagePath');
|
|
}
|
|
|
|
image = _imageResizer.resizeToFit(image);
|
|
|
|
final w = image.width;
|
|
final h = image.height;
|
|
final stride = (w * 16 + 7) ~/ 8;
|
|
|
|
final header = ByteData(12);
|
|
header.setUint8(0, _magic);
|
|
header.setUint8(1, _colorFormatRgb565);
|
|
header.setUint16(2, _flags, Endian.little);
|
|
header.setUint16(4, w, Endian.little);
|
|
header.setUint16(6, h, Endian.little);
|
|
header.setUint16(8, stride, Endian.little);
|
|
header.setUint16(10, 0, Endian.little); // reserved
|
|
|
|
final body = ByteData(w * h * 2);
|
|
var offset = 0;
|
|
for (var y = 0; y < h; y++) {
|
|
for (var x = 0; x < w; x++) {
|
|
final pixel = image.getPixel(x, y);
|
|
final rgb565 = _toRgb565(pixel.r.toInt(), pixel.g.toInt(), pixel.b.toInt());
|
|
body.setUint16(offset, rgb565, Endian.little);
|
|
offset += 2;
|
|
}
|
|
}
|
|
|
|
final binFile = File(binPath);
|
|
await binFile.parent.create(recursive: true);
|
|
await binFile.writeAsBytes([
|
|
...header.buffer.asUint8List(),
|
|
...body.buffer.asUint8List(),
|
|
]);
|
|
}
|
|
}
|
|
|