이미지 저장(sqflite)

이원석·2023년 12월 22일
0

Flutter

목록 보기
41/46

이미지 저장

image_picker로 가져온 이미지를 sqflite를 이용해 DB에 저장
path_providerdart:io library를 이용해 파일을 쓰고 지우는 방법도 있다고 하지만 그건 추후 정리

이미지 model 생성

Uint8List은 고정된 길이의 8bit의 부호없는 정수 List이다

class Memo {
  int id;
  int isImage;
  String memo;
  Uint8List image;

  Memo.fromJson(Map<String, dynamic> memo)
      : id = memo['id'],
        isImage = memo['isImage'],
        memo = memo['memo'],
        image = memo['image'];

  Map<String, dynamic> toMap() {
    return {
      'id': id,
      'isImage': isImage,
      'memo': memo,
      'image': image,
    };
  }
}

DB 생성

테이블의 컬럼에 BLOB 타입은 Binary Large object 타입으로 이미지 등 용량이 큰 바이너리 데이터를 저장할 수 있다.

class MemoProvider {
  final String tableMemo = 'memo';
  final String columnId = 'id';
  final String columnIsImage = 'isImage';
  final String columnMemo = 'memo';
  final String columnImage = 'image';

  Database? db;

  Future<Database> get database async {
    if (db != null) return db!;
    await init();
    return db!;
  }

  Future init() async {
    db = await openDatabase(
      join(await getDatabasesPath(), 'memo_database.db'),
      onCreate: onCreateDB,
      version: 1,
    );
  }

  Future<void> onCreateDB(Database db, int version) {
    return db.execute('''create table $tableMemo ( 
  $columnId integer primary key autoincrement, 
  $columnIsImage integer not null,
  $columnMemo text,
  $columnImage BLOB)''');
  }

  Future<void> insert(Map<String, dynamic> memo) async {
    final db = await database;
    await db.insert(tableMemo, memo);
  }

  Future<List<Memo>> memos() async {
    final db = await database;
    List<Memo> memos = [];

    final List<Map<String, dynamic>> maps = await db.query(
      tableMemo,
      orderBy: "$columnId desc",
    );
    for (var map in maps) {
      memos.add(Memo.fromJson(map));
    }
    return memos;
  }

  Future<void> update(Memo memo) async {
    final db = await database;
    await db.update(
      tableMemo,
      memo.toMap(),
      where: '$columnId = ?',
      whereArgs: [memo.id],
    );
  }

  Future<void> delete(int id) async {
    final db = await database;
    await db.delete(
      tableMemo,
      where: '$columnId = ?',
      whereArgs: [id],
    );
  }
}

이미지 가져오기

final ImagePicker picker = ImagePicker();
  XFile? image;

 void getImage() async {
    image = await picker.pickImage(source: ImageSource.gallery);
    if (image != null) {
      await insertMemo(image!);
      setState(() {
        memos = memoProvider.memos();
      });
    }
  }

이미지 저장(+ image to Uint8List)

readAsBytes함수는 Future<Uint8List>을 반환하고 전체 파일 내용을 바이트 목록으로 읽는다.(이미지 파일을 Uint8List 형태로 바꿀때 사용)
await을 붙여주어 객체를 생성할때 Future<Uint8List>이 아닌 Uint8List타입으로 받을 수 있게 한다.

final MemoProvider memoProvider = MemoProvider();
  late Future<List<Memo>> memos = memoProvider.memos();

  Future<void> insertMemo(XFile image) async {
    Map<String, dynamic> newmemo = ({
      'isImage': 1,
      'memo': '',
      'image':
          await image.readAsBytes(), //await을 넣지 않으면 Future<Uint8List> 형이 들어감
    });
    await memoProvider.insert(newmemo);
  }

Uint8List to image

저장된 Uint8Listimage로 변환

static Image uint8listToImage(Uint8List uint8list) {
    Image image;
    image = Image.memory(uint8list);
    return image;
  }

0개의 댓글