image_picker
로 가져온 이미지를 sqflite
를 이용해 DB에 저장
path_provider
와 dart:io library
를 이용해 파일을 쓰고 지우는 방법도 있다고 하지만 그건 추후 정리
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,
};
}
}
테이블의 컬럼에 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();
});
}
}
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
를 image
로 변환
static Image uint8listToImage(Uint8List uint8list) {
Image image;
image = Image.memory(uint8list);
return image;
}