perf: improve image resizing

This commit is contained in:
Gordon Hayes
2022-08-10 14:36:39 +02:00
parent 6afde872e5
commit 55bb828bd1
3 changed files with 35 additions and 10 deletions
@@ -100,6 +100,7 @@ class StreamFileAttachment extends StreamAttachmentWidget {
borderRadius: BorderRadius.circular(8), borderRadius: BorderRadius.circular(8),
); );
// TODO: Improve image memory. This is using the full image instead of a smaller version (thumbnail)
Widget _getFileTypeImage(BuildContext context) { Widget _getFileTypeImage(BuildContext context) {
if (isImageAttachment) { if (isImageAttachment) {
return Material( return Material(
@@ -71,16 +71,20 @@ class StreamImageAttachment extends StreamAttachmentWidget {
var imageUri = Uri.parse(imageUrl); var imageUri = Uri.parse(imageUrl);
if (imageUri.host.endsWith('stream-io-cdn.com') && if (imageUri.host.endsWith('stream-io-cdn.com') &&
imageUri.queryParameters['h'] == '*' && (imageUri.queryParameters['h'] == null ||
imageUri.queryParameters['w'] == '*' && imageUri.queryParameters['h'] == '*') &&
imageUri.queryParameters['crop'] == '*' && (imageUri.queryParameters['w'] == null ||
imageUri.queryParameters['resize'] == '*') { imageUri.queryParameters['w'] == '*') &&
(imageUri.queryParameters['crop'] == null ||
imageUri.queryParameters['crop'] == '*') &&
(imageUri.queryParameters['resize'] == null ||
imageUri.queryParameters['resize'] == '*')) {
imageUri = imageUri.replace(queryParameters: { imageUri = imageUri.replace(queryParameters: {
...imageUri.queryParameters, ...imageUri.queryParameters,
'h': '400', 'h': '400', // TODO: Are these sizes optimal? Consider web/desktop
'w': '400', 'w': '400',
'crop': 'center', 'crop': 'center',
'resize': 'crop', 'resize': 'clip',
}); });
} else if (imageUri.host.endsWith('stream-cloud-uploads.imgix.net')) { } else if (imageUri.host.endsWith('stream-cloud-uploads.imgix.net')) {
imageUri = imageUri.replace(queryParameters: { imageUri = imageUri.replace(queryParameters: {
@@ -1,4 +1,6 @@
import 'dart:async'; import 'dart:async';
import 'dart:io';
import 'dart:math' as math;
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_svg/flutter_svg.dart';
@@ -371,13 +373,31 @@ class _StreamAttachmentPickerState extends State<StreamAttachmentPicker> {
void _addAssetAttachment(AssetEntity medium) async { void _addAssetAttachment(AssetEntity medium) async {
final mediaFile = await medium.originFile; final mediaFile = await medium.originFile;
if (mediaFile == null) return; if (mediaFile == null) return;
final tempDir = await getTemporaryDirectory(); final tempDir = await getTemporaryDirectory();
final cachedFile = await mediaFile // TODO: Confirm that this max resolution is final
.copy('${tempDir.path}/${mediaFile.path.split('/').last}'); const maxCDNImageResolution = 16800000;
final imageResolution = medium.width * medium.height;
File? cachedFile;
if (imageResolution > maxCDNImageResolution) {
final aspect = imageResolution / maxCDNImageResolution;
final updatedSize = medium.size / (math.sqrt(aspect));
final resizedImage = await medium.thumbnailDataWithSize(
ThumbnailSize(
updatedSize.width.floor(),
updatedSize.height.floor(),
),
quality: 30, // TODO: investigate compressing all images
);
cachedFile =
await File('${tempDir.path}/${mediaFile.path.split('/').last}')
.create()
..writeAsBytesSync(resizedImage!);
} else {
cachedFile = await mediaFile
.copy('${tempDir.path}/${mediaFile.path.split('/').last}');
}
final file = AttachmentFile( final file = AttachmentFile(
path: cachedFile.path, path: cachedFile.path,