docx_reader/lib/replace.dart

91 lines
2.4 KiB
Dart
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import 'dart:io';
import 'dart:typed_data';
import 'dart:math';
class ReplaceContent {
DocxImage? img;
String? value; /// Only Text to replace; null if it's image!
ReplaceContent({this.value, this.img}) {
if (img != null && value != null)
throw StateError('Can\'t have value and image define');
if (img == null && value == null)
throw StateError('You need define value or image');
}
}
/// 16cm * 360 000 = 5760000 EMU
const int maxWidth = 16 * 360000;
/// 24cm * 360 000 = 8640000 EMU
const int maxHeight = 24 * 360000;
class DocxImage {
int? id;
int? sizeX; /// in EMU
int? sizeY; /// in EMU
late File file;
/// [file] support JPG/JPEG and PNG
/// [sizeX] and [sizeY] use EMU metrics BUT init a instance in PIXEL
DocxImage({required File file, this.sizeX, this.sizeY}) {
this.file = file;
if (sizeX == null && sizeY == null) {
Uint8List bytes = file.readAsBytesSync();
String extensions = file.path.substring(file.path.lastIndexOf('.') + 1);
if (extensions == 'png') {
sizeX = (bytes.buffer.asByteData().getUint32(16)) * 9525;
sizeY = (bytes.buffer.asByteData().getUint32(20)) * 9525;
}
else if (extensions == 'jpg' || extensions == 'jpeg') {
List<int> sizes = getSizeJpg(bytes);
if (sizes.isEmpty)
throw StateError('Can\'t get the size of Jpg image');
sizeX = sizes[0];
sizeY = sizes[1];
}
}
else if (sizeX != null && sizeY != null) {
sizeX = sizeX! * 9525;
sizeY = sizeY! * 9525;
}
else
throw StateError('Only sizeX or sizeY is defined!');
// Limit size of image
double scale = min(maxWidth / sizeX!, maxHeight / sizeY!);
scale = scale > 1 ? 1 : scale;
sizeX = (sizeX! * scale).round();
sizeY = (sizeY! * scale).round();
}
}
/// Return size of Jpg => [width, height]
List<int> getSizeJpg(Uint8List bytes) {
int i = 0;
while (i < bytes.length) {
while(bytes[i]==0xff)
i++;
int marker = bytes[i++];
if(marker==0xd8) // SOI
continue;
if(marker==0xd9) // EOI
break;
if(0xd0<=marker && marker<=0xd7)
continue;
if(marker==0x01) // TEM
continue;
int length = (bytes[i] << 8) | bytes[i + 1];
i += 2;
if (marker == 0xc0)
return [(bytes[i + 1] << 8) + bytes[i + 2], // Width
(bytes[i + 3] << 8) + bytes[i + 4]]; // Height
i += length - 2;
}
return [];
}