[Flutter] 'image' 패키지를 사용한 이미지 압축

임효진·2024년 6월 11일
0

Flutter

목록 보기
19/22

이미지를 서버로 업로드할 때 이미지 크기가 너무 크면 전송 시간이 오래 걸리고, 네트워크 대역폭을 많이 차지할 수 있다.
이를 해결하기 위해 Flutter에서는 이미지 파일을 압축할 수 있다.
이 글에서는 image 패키지를 사용하여 이미지를 압축하는 방법을 알아보겠다.

다른 이미지 처리 패키지들과의 비교

이미지 처리를 위해 Flutter에서 사용할 수 있는 여러 패키지가 있다.
그 중 대표적인 패키지로는 image, flutter_image_compress, image_picker, compressor 등이 있다.
각 패키지의 장단점을 비교해 보겠다.

image 패키지

장점:
완전한 Dart로 작성되어 있어 플랫폼에 의존하지 않는다.
다양한 이미지 처리 기능을 제공한다다 (크기 조정, 자르기, 포맷 변경 등).
설치 및 사용이 간편하다.
단점:
매우 큰 이미지 파일을 처리할 때 성능이 떨어질 수 있다.

flutter_image_compress 패키지

장점:
iOS와 Android 네이티브 코드를 사용하여 이미지를 압축한다.
성능이 우수하며, 이미지 품질을 세밀하게 조정할 수 있다.
단점:
플랫폼에 종속적이므로 플랫폼 별 설정이 필요하다.
네이티브 코드에 의존하므로, Dart 환경에서는 직접 사용하기 어렵다.

image_picker 패키지

장점:
이미지를 갤러리에서 선택하거나 카메라로 촬영할 수 있다.
Flutter에서 매우 널리 사용되며, 간편하게 이미지를 선택할 수 있다.
단점:
이미지 처리 기능이 제한적이다 (크기 조정, 압축 기능이 없음).

compressor 패키지

장점:
간단한 API로 이미지를 압축할 수 있다.
기본적인 압축 기능을 제공한다.
단점:
다른 패키지들에 비해 기능이 제한적이다.
이미지 크기 조정, 자르기 등의 고급 기능이 부족하다.

왜 image 패키지를 선택했는가?

image 패키지는 완전한 Dart로 작성되어 있어 플랫폼에 독립적이며, 다양한 이미지 처리 기능을 제공한다는 점에서 매우 유용하다.
특히, 이미지의 크기를 조정하고, 포맷을 변경하며, 이미지 품질을 조정하는 등의 작업을 하나의 패키지로 수행할 수 있다.
또한, 플랫폼 별 설정 없이 간편하게 설치하고 사용할 수 있어,
Flutter 프로젝트에서 이미지 처리를 위해 가장 적합한 선택이라고 판단했다.

image 패키지를 통한 예제

pubspec.yaml 파일에 image 패키지를 추가한다.

dependencies:
  flutter:
    sdk: flutter
  image: ^4.2.0

이 압축 기능 구현

다음은 Flutter에서 image 패키지를 사용하여 이미지를 압축하는 예제다.
이 예제는 이미지의 크기를 조정하고, JPEG 포맷으로 압축하는 방법을 보여준다.

import 'dart:io';
import 'package:flutter/material.dart';
import 'package:image/image.dart' as img;
import 'package:image_picker/image_picker.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  
  Widget build(BuildContext context) {
    return MaterialApp(
      home: ImageCompressScreen(),
    );
  }
}

class ImageCompressScreen extends StatefulWidget {
  
  _ImageCompressScreenState createState() => _ImageCompressScreenState();
}

class _ImageCompressScreenState extends State<ImageCompressScreen> {
  File? _image;
  final ImagePicker _picker = ImagePicker();

  /* 이미지 선택 및 압축 메서드 */
  Future<void> _pickAndCompressImage() async {
    final XFile? image = await _picker.pickImage(source: ImageSource.gallery);
    if (image != null) {
      final File compressedImage = await _compressImage(File(image.path));
      setState(() {
        _image = compressedImage;
      });
    }
  }

  /* 이미지 압축 메서드 */
  Future<File> _compressImage(File imageFile) async {
    final bytes = await imageFile.readAsBytes();
    img.Image image = img.decodeImage(bytes)!;

    // 이미지 크기를 조정 (예: 너비를 1024로 설정)
    img.Image resizedImage = img.copyResize(image, width: 1024);

    // 압축된 이미지 파일 생성 (JPEG 품질을 85로 설정)
    final compressedBytes = img.encodeJpg(resizedImage, quality: 85);
    final compressedImageFile = File('${imageFile.path}_compressed.jpg')
      ..writeAsBytesSync(compressedBytes);

    return compressedImageFile;
  }

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Image Compression Example')),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            _image == null
                ? Text('No image selected.')
                : Image.file(_image!),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: _pickAndCompressImage,
              child: Text('Pick and Compress Image'),
            ),
          ],
        ),
      ),
    );
  }
}

코드 설명

패키지 임포트

image 패키지와 image_picker 패키지를 임포트한다.
image_picker 패키지는 갤러리에서 이미지를 선택하는 데 사용된다.

이미지 선택 및 압축

_pickAndCompressImage 메서드는 이미지를 선택하고 압축한다.
사용자가 이미지를 선택하면, _compressImage 메서드가 호출되어 이미지를 압축한다.

이미지 압축:
_compressImage 메서드는 다음 단계를 수행한다:

이미지 파일을 바이트 배열로 읽는다.
image 패키지를 사용하여 이미지를 디코딩한다.
copyResize 메서드를 사용하여 이미지 크기를 조정한다.
encodeJpg 메서드를 사용하여 이미지 품질을 설정하고 JPEG 포맷으로 압축한다.
압축된 바이트 배열을 새 파일로 저장한다.
UI 구성:
사용자가 이미지를 선택하고 압축된 이미지를 화면에 표시할 수 있도록 UI를 구성한다.

profile
핫바리임

0개의 댓글