Description
Use case
Currently, Syncfusion's PdfBitmap class does not natively support WebP (.webp) image files. When attempting to draw WebP images directly using PdfBitmap(Uint8List webpBytes), it results in an "Invalid/Unsupported image stream" error. Looking at the code I can see there isn't a decoder implemented.
My case is that WebP is an increasingly popular image format that offers superior compression (both lossy and lossless) compared to JPEG and PNG, often resulting in significantly smaller file sizes without sacrificing quality. More specifically my business currently compresses all user uploaded images to reduce our backend weight and download sizes. We often have users exporting form data out, which we use syncfusion_flutter_pdf to generate.
Proposal
My request is that the internal method
static ImageDecoder? getDecoder(List<int> data) {
has a WebPDecoder implemented here.
Current I am able to check for webp images using..
static bool _isWebp(List<int> imageData) {
if (imageData.length >= 12) {
return imageData[0] == 0x52 &&
imageData[1] == 0x49 &&
imageData[2] == 0x46 &&
imageData[3] == 0x46 &&
imageData[8] == 0x57 &&
imageData[9] == 0x45 &&
imageData[10] == 0x42 &&
imageData[11] == 0x50;
}
return false;
}
I did come up with a workaround of converting back to png, but its obviously less ideal.
try {
//Draw document image
bool isWebP = _isWebp(uint8list);
if (isWebP) {
print('Detected WebP image. Decoding and converting to PNG...');
final img.WebPDecoder webpDecoder = img.WebPDecoder();
final img.Image? decodedWebp = webpDecoder.decode(uint8list);
if (decodedWebp != null) {
// Successfully decoded WebP
uint8list = Uint8List.fromList(img.encodePng(decodedWebp));
print('WebP converted to PNG. New size: ${uint8list.length} bytes');
} else {
throw Exception('Failed to decode WebP image.');
}
}
final PdfBitmap image = PdfBitmap(uint8list);