[FLUTTER] 이미지 사이즈 줄이기

길위에 히피·2024년 8월 27일
0

Flutter

목록 보기
35/44

이미지는 웹사이트, 앱, 소셜 미디어 등 다양한 플랫폼에서 중요한 요소로 자리 잡았습니다. 그러나 고해상도 이미지의 사용은 페이지 로딩 속도를 느리게 하고, 이는 사용자 경험에 부정적인 영향을 미칠 수 있습니다. 이러한 문제를 해결하기 위해 이미지 압축은 필수적인 과정입니다. 이번 에서는 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에서의 이미지 압축에 대해 더 궁금한 점이 있다면, 댓글로 질문을 남겨 주세요!

profile
마음맘은 히피인 일꾼러

0개의 댓글