이미지는 웹사이트, 앱, 소셜 미디어 등 다양한 플랫폼에서 중요한 요소로 자리 잡았습니다. 그러나 고해상도 이미지의 사용은 페이지 로딩 속도를 느리게 하고, 이는 사용자 경험에 부정적인 영향을 미칠 수 있습니다. 이러한 문제를 해결하기 위해 이미지 압축은 필수적인 과정입니다. 이번 에서는 Flutter 앱에서 이미지 압축 기능을 구현하는 방법에 대해 알아보겠습니다.
Flutter에서 이미지를 압축하기 위해 flutter_image_compress 패키지를 사용할 수 있습니다. 이 패키지는 다양한 이미지 포맷을 지원하며, 간단한 방법으로 이미지 파일 크기를 줄일 수 있습니다. 아래는 Flutter에서 이미지 압축 기능을 구현하는 코드입니다.
import 'dart:io';
import 'dart:math' as math;
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_image_compress/flutter_image_compress.dart';
import 'package:path_provider/path_provider.dart';
class UtilImageResize {
Future<List<String?>> compressImage(List<String?> paths) async {
return await Future.wait(paths.map((name) async {
if (name != null && !name.endsWith('.gif')) {
var file = File(name);
var decodedImage = await decodeImageFromList(await file.readAsBytes());
var compressedFile = await _compressFile(
imageBytes: await file.readAsBytes(),
tempName: name.split("/").last,
srcWidth: decodedImage.width,
srcHeight: decodedImage.height,
);
if (compressedFile != null) {
return compressedFile.path;
}
}
return name;
}));
}
Future<List<File>> compressImageWeb(List<XFile> files) async {
return await Future.wait(files.map((file) async {
var decodedImage = await decodeImageFromList(await file.readAsBytes());
var compressedFile = await _compressFile(
imageBytes: await file.readAsBytes(),
tempName: file.path.split("/").last,
srcWidth: decodedImage.width,
srcHeight: decodedImage.height,
);
return compressedFile ?? File(file.path);
}));
}
Future<File?> _compressFile({
required Uint8List imageBytes,
required String tempName,
required int srcWidth,
required int srcHeight,
}) async {
var scale = calcScale(srcHeight: srcHeight, srcWidth: srcWidth);
if (scale > 1) {
try {
Uint8List? result = await FlutterImageCompress.compressWithList(
imageBytes,
minWidth: (srcWidth / scale).round(),
minHeight: (srcHeight / scale).round(),
quality: 80,
);
if (result != null) {
final tempDir = await getTemporaryDirectory();
final tempPath = '${tempDir.path}/$tempName';
File tempFile = File(tempPath);
await tempFile.writeAsBytes(result);
return tempFile;
}
} catch (e) {
print("Error compressing image: $e");
}
}
return null;
}
double calcScale({
required int srcWidth,
required int srcHeight,
}) {
var scaleW = srcWidth / 1024;
var scaleH = srcHeight / 1024;
var scale = math.max(1.0, math.min(scaleW, scaleH));
return scale;
}
}
compressImage와 compressImageWeb 메서드: 이 두 메서드는 각각 로컬 파일과 웹 파일의 이미지를 압축합니다. 압축 과정은 파일을 읽어 들여, 스케일을 계산한 후, FlutterImageCompress 패키지를 사용해 이미지를 압축합니다.
_compressFile 메서드: 이 메서드는 실제 압축 작업을 수행합니다. 이미지의 크기를 1024px 이하로 줄이도록 스케일을 계산하고, 압축된 이미지를 임시 파일로 저장합니다.
스케일 계산: 이미지의 가로, 세로 크기를 바탕으로, 압축해야 할 크기를 계산합니다. 이는 이미지의 해상도를 최적화하여 파일 크기를 줄이기 위한 필수 단계입니다.
이미지 압축을 성공적으로 구현했다면, 다음과 같은 최적화 및 확장 작업을 고려할 수 있습니다.
다양한 이미지 포맷 지원: JPEG, PNG 외에도 WebP 등 다양한 포맷을 지원하여, 더욱 효율적인 압축을 제공할 수 있습니다.
에러 처리 및 로그: 압축 중 발생할 수 있는 예외 상황을 처리하고, 로그를 남겨 문제를 추적할 수 있도록 개선합니다.
비동기 처리 최적화: Future.forEach 대신 Future.wait를 사용하여 비동기 처리를 최적화하고, 성능을 개선할 수 있습니다.
이미지 압축은 사용자 경험과 성능을 향상시키는 중요한 요소입니다. 특히 Flutter와 같은 크로스 플랫폼 환경에서는 다양한 기기에서 최적의 성능을 제공하기 위해 필수적인 기능입니다. 이 블로그에서 제시한 코드를 활용하여, 손쉽게 이미지 압축 기능을 구현해 보세요. 이를 통해 앱의 효율성을 높이고, 사용자 만족도를 크게 향상시킬 수 있을 것입니다.
Flutter에서의 이미지 압축에 대해 더 궁금한 점이 있다면, 댓글로 질문을 남겨 주세요!