flutter_image_compress
flutter_image_compress copied to clipboard
Provide an option to set max width and height
Hi,
Thanks for providing this assume package. I would like to ask if it's possible to add a feature to specify max width and height when compressing the image. This way we can set a limit on the size of the resulting file regardless of the size of the original image. The exact issue that I'm facing is that I don't know if the user will upload a 4MB image or a 100KB image that was already compressed somewhere else. Do you suggest making the quality parameter a function of the original size of the image as a temporary solution at least?
Best,
Both max and min have problems that involve priority. So temporarily will not increase the max related attributes.
Closing #84 and adding the details to this issue.
Diving in some implementation details, given a maximum dimension of 1280 x 1280, this package would identify which side is larger (height or width), resize this side to 1280 and resize the other side keeping the original aspect ratio. It is important to know which side is larger because if you resize the smaller side to 1280 and resize the larger one to keep the aspect ratio, the latter size would be larger than 1280.
For example, considering a maximum dimension of 1280 x 1280, a 4000 x 3000 image would become 1280 x 960.
I think the max size is most needed, not min size. I try to found someway to resize image by myself, but surprisingly, I can't find anyway to get image raw pixel size in flutter or dart... WTF..
@xpader give this a shot, given an Image originalImage:
import 'dart:ui';
final thumbnailImage = await instantiateImageCodec(event.rawImageData,
targetHeight:
originalImage.height <= originalImage.width ? 300 : null,
targetWidth:
originalImage.width <= originalImage.height ? 300 : null)
.then((c) => c.getNextFrame())
.then((f) => f.image);
If you're starting with a Uint8List, try:
import 'package:flutter/widgets.dart';
final originalImage = await decodeImageFromList(event.rawImageData);
@xpader give this a shot, given an
Image originalImage:import 'dart:ui'; final thumbnailImage = await instantiateImageCodec(event.rawImageData, targetHeight: originalImage.height <= originalImage.width ? 300 : null, targetWidth: originalImage.width <= originalImage.height ? 300 : null) .then((c) => c.getNextFrame()) .then((f) => f.image);If you're starting with a
Uint8List, try:import 'package:flutter/widgets.dart'; final originalImage = await decodeImageFromList(event.rawImageData);
Yes, I found this way too, and another way use image package, has a method copyResize to resize image, but this two way resize image used too much time. and after resize, the image file size is bigger than before..
This is still an issue. On Android I used
val bitmap = GlideApp.with(context!!)
.asBitmap()
.override(
AppConstants.MAX_PICTURE_RESOLUTION_WIDTH,
AppConstants.MAX_PICTURE_RESOLUTION_HEIGHT
)
.fitCenter()
.load(uri)
.submit().get()
I can't find an equivalent on Flutter. With those params
var scale = calcScale(
srcWidth: 4000,
srcHeight: 2000,
minWidth: 1920,
minHeight: 1080,
);
The current result is width = 2160.0, height = 1080.0. I need the result to be width = 1920.0, height = 960.0. Is there any way to achieve that?
Here is my work around to get the proper minWidth and minHeight:
Size getCompressionSize(sourceWidth, sourceHeight, minWidth, minHeight){
if (minWidth >= sourceWidth && minHeight >= sourceHeight) return Size(minWidth, minHeight);
double _width = minWidth;
double _height = minHeight;
final double inputAspectRatio = sourceWidth/sourceHeight;
final double targetAspectRatio = minWidth/minHeight;
if (inputAspectRatio <= 1){
_width = minHeight*inputAspectRatio;
}else{
//inputAspectRatio > 1
if (inputAspectRatio > targetAspectRatio){
_height = minWidth/inputAspectRatio;
}else{
_width = minHeight/targetAspectRatio;
}
}
return Size(_width, _height);
}
The method will adjust the value to simulate the 'maxWidth' and 'maxHeight' params, e.g. the output image width will never be higher than 'minWidth' and the output image height never higher than 'minHeight'. The source resolution is also preserved. The Size values are the values you pass to FlutterImageCompress.
any progress on this?
I solved it by using flutter_native_image
Future<File?> getMaxResizedImage(String imagePath) async {
ImageProperties prop = await FlutterNativeImage.getImageProperties(imagePath);
if (prop.width == null || prop.height == null) return null;
var maxSize = 1024;
var targetWidth = 1;
var targetHeight = 1;
if (prop.width! > prop.height!) {
targetWidth = min(maxSize, prop.width!);
targetHeight = (prop.height! * targetWidth / prop.width!).round();
} else {
targetHeight = min(maxSize, prop.height!);
targetWidth = (prop.width! * targetHeight / prop.height!).round();
}
return await FlutterNativeImage.compressImage(
imagePath, quality: 100,
targetWidth: targetWidth,
targetHeight: targetHeight,
);
}