TF-761 Implement compress inside download and transformer
This commit is contained in:
@@ -1,15 +1,22 @@
|
|||||||
|
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
import 'dart:typed_data';
|
||||||
|
|
||||||
import 'package:core/core.dart';
|
import 'package:core/data/network/dio_client.dart';
|
||||||
|
import 'package:core/data/utils/compress_file_utils.dart';
|
||||||
|
import 'package:core/presentation/extensions/html_extension.dart';
|
||||||
|
import 'package:core/utils/app_logger.dart';
|
||||||
|
import 'package:core/utils/build_utils.dart';
|
||||||
import 'package:dio/dio.dart';
|
import 'package:dio/dio.dart';
|
||||||
|
import 'package:flutter/foundation.dart';
|
||||||
|
|
||||||
class DownloadClient {
|
class DownloadClient {
|
||||||
|
|
||||||
final DioClient _dioClient;
|
final DioClient _dioClient;
|
||||||
|
final CompressFileUtils _compressFileUtils;
|
||||||
|
|
||||||
DownloadClient(this._dioClient);
|
DownloadClient(this._dioClient, this._compressFileUtils);
|
||||||
|
|
||||||
Future<ResponseBody> downloadFile(
|
Future<ResponseBody> downloadFile(
|
||||||
String url,
|
String url,
|
||||||
@@ -28,14 +35,84 @@ class DownloadClient {
|
|||||||
return (responseBody as ResponseBody);
|
return (responseBody as ResponseBody);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<String?> downloadImageAsBase64(String url) async {
|
Future<String?> downloadImageAsBase64(
|
||||||
|
String url,
|
||||||
|
String cid,
|
||||||
|
String fileExtension,
|
||||||
|
String fileName,
|
||||||
|
{
|
||||||
|
Uint8List? bytesData,
|
||||||
|
double? maxWidth,
|
||||||
|
bool? compress,
|
||||||
|
}
|
||||||
|
) async {
|
||||||
try {
|
try {
|
||||||
final response = await _dioClient.get(
|
if (bytesData == null) {
|
||||||
url,
|
log('DownloadClient::downloadImageAsBase64(): bytesData is NULL');
|
||||||
options: Options(responseType: ResponseType.bytes));
|
bytesData = await _dioClient.get(url, options: Options(responseType: ResponseType.bytes));
|
||||||
return base64Encode(response);
|
}
|
||||||
|
|
||||||
|
if (bytesData == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (BuildUtils.isWeb) {
|
||||||
|
final base64Uri = encodeToBase64Uri({
|
||||||
|
'bytesData': bytesData,
|
||||||
|
'mimeType': 'image/$fileExtension',
|
||||||
|
'cid': cid,
|
||||||
|
'fileName': fileName
|
||||||
|
});
|
||||||
|
|
||||||
|
return base64Uri;
|
||||||
|
} else {
|
||||||
|
if (compress == true) {
|
||||||
|
final bytesDataCompressed = await _compressFileUtils.compressBytesDataImage(
|
||||||
|
bytesData,
|
||||||
|
maxWidth: maxWidth?.toInt());
|
||||||
|
|
||||||
|
final base64Uri = await compute(encodeToBase64Uri, {
|
||||||
|
'bytesData': bytesDataCompressed,
|
||||||
|
'mimeType': 'image/$fileExtension',
|
||||||
|
'cid': cid,
|
||||||
|
'fileName': fileName
|
||||||
|
});
|
||||||
|
|
||||||
|
return base64Uri;
|
||||||
|
} else {
|
||||||
|
final base64Uri = await compute(encodeToBase64Uri, {
|
||||||
|
'bytesData': bytesData,
|
||||||
|
'mimeType': 'image/$fileExtension',
|
||||||
|
'cid': cid,
|
||||||
|
'fileName': fileName
|
||||||
|
});
|
||||||
|
|
||||||
|
return base64Uri;
|
||||||
|
}
|
||||||
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return url;
|
log('DownloadClient::downloadImageAsBase64(): ERROR: $e');
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static String encodeToBase64Uri(Map<String, dynamic> entryParam) {
|
||||||
|
var bytesData = entryParam['bytesData'];
|
||||||
|
var mimeType = entryParam['mimeType'];
|
||||||
|
final cid = entryParam['cid'];
|
||||||
|
var fileName = entryParam['fileName'];
|
||||||
|
|
||||||
|
final base64Data = base64Encode(bytesData);
|
||||||
|
if (mimeType.endsWith('svg')) {
|
||||||
|
mimeType = 'image/svg+xml';
|
||||||
|
}
|
||||||
|
if (!base64Data.endsWith('==')) {
|
||||||
|
base64Data.append('==');
|
||||||
|
}
|
||||||
|
if (fileName.contains('.')) {
|
||||||
|
fileName = fileName.split('.').first;
|
||||||
|
}
|
||||||
|
final base64Uri = '<img src="data:$mimeType;base64,$base64Data" alt="$fileName" id="$cid" style="max-width: 100%" />';
|
||||||
|
return base64Uri;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -4,6 +4,7 @@ import 'dart:convert';
|
|||||||
import 'package:core/core.dart';
|
import 'package:core/core.dart';
|
||||||
import 'package:core/presentation/utils/html_transformer/base/dom_transformer.dart';
|
import 'package:core/presentation/utils/html_transformer/base/dom_transformer.dart';
|
||||||
import 'package:dio/dio.dart';
|
import 'package:dio/dio.dart';
|
||||||
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:html/dom.dart';
|
import 'package:html/dom.dart';
|
||||||
|
|
||||||
class ImageTransformer extends DomTransformer {
|
class ImageTransformer extends DomTransformer {
|
||||||
@@ -19,6 +20,7 @@ class ImageTransformer extends DomTransformer {
|
|||||||
DioClient? dioClient
|
DioClient? dioClient
|
||||||
}
|
}
|
||||||
) async {
|
) async {
|
||||||
|
final compressFileUtils = CompressFileUtils();
|
||||||
final imageElements = document.getElementsByTagName('img');
|
final imageElements = document.getElementsByTagName('img');
|
||||||
|
|
||||||
await Future.wait(imageElements.map((imageElement) async {
|
await Future.wait(imageElements.map((imageElement) async {
|
||||||
@@ -32,24 +34,50 @@ class ImageTransformer extends DomTransformer {
|
|||||||
final cid = src.replaceFirst('cid:', '').trim();
|
final cid = src.replaceFirst('cid:', '').trim();
|
||||||
final cidUrlDownload = mapUrlDownloadCID[cid];
|
final cidUrlDownload = mapUrlDownloadCID[cid];
|
||||||
if (cidUrlDownload != null && cidUrlDownload.isNotEmpty && dioClient != null) {
|
if (cidUrlDownload != null && cidUrlDownload.isNotEmpty && dioClient != null) {
|
||||||
final imgBase64 = await loadAsyncNetworkImageToBase64(dioClient, cidUrlDownload);
|
final imgBase64Uri = await loadAsyncNetworkImageToBase64(
|
||||||
if (imgBase64 != null && imgBase64.isNotEmpty) {
|
dioClient,
|
||||||
imageElement.attributes['src'] = 'data:image/jpeg;base64,$imgBase64';
|
compressFileUtils,
|
||||||
|
cidUrlDownload);
|
||||||
|
if (imgBase64Uri.isNotEmpty) {
|
||||||
|
imageElement.attributes['src'] = imgBase64Uri;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<String> loadAsyncNetworkImageToBase64(
|
||||||
Future<String?> loadAsyncNetworkImageToBase64(DioClient dioClient, String imageUrl) async {
|
DioClient dioClient,
|
||||||
|
CompressFileUtils compressFileUtils,
|
||||||
|
String imageUrl
|
||||||
|
) async {
|
||||||
try {
|
try {
|
||||||
final response = await dioClient.get(
|
var responseData = await dioClient.get(
|
||||||
imageUrl,
|
imageUrl,
|
||||||
options: Options(responseType: ResponseType.bytes));
|
options: Options(responseType: ResponseType.bytes));
|
||||||
return base64Encode(response);
|
|
||||||
|
if (responseData != null) {
|
||||||
|
if (BuildUtils.isWeb) {
|
||||||
|
return encodeToBase64Uri(responseData);
|
||||||
|
} else {
|
||||||
|
final bytesCompressed = await compressFileUtils.compressBytesDataImage(responseData);
|
||||||
|
final base64Uri = await compute(encodeToBase64Uri, bytesCompressed);
|
||||||
|
return base64Uri;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return imageUrl;
|
return '';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static String encodeToBase64Uri(dynamic bytesData) {
|
||||||
|
final base64Data = base64Encode(bytesData);
|
||||||
|
if (!base64Data.endsWith('==')) {
|
||||||
|
base64Data.append('==');
|
||||||
|
}
|
||||||
|
final base64Uri = 'data:image/jpeg;base64,$base64Data';
|
||||||
|
return base64Uri;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user