use crate::Board; use std::io; use std::io::{ Write, Read, Cursor }; use std::fs::File; use std::path::Path; use image::io::Reader as ImageReader; use image::DynamicImage; pub fn write_board_to_file(board: &Board, image: Option<&DynamicImage>, path: &Path) -> io::Result<()> { let file = File::create(path)?; let mut ar = zip::ZipWriter::new(file); let options = zip::write::FileOptions::default(); ar.start_file("graph.json", options)?; ar.write_all(&serde_json::to_vec(board)?)?; if let Some(image) = image { ar.start_file("image.png", options)?; let data = encode_png(image); ar.write_all(&data)?; ar.flush()?; } ar.finish()?; Ok(()) } pub fn read_board_from_file(path: &Path) -> io::Result<(Board, Option)> { let file = File::open(path)?; let mut ar = zip::ZipArchive::new(file)?; let json_file = ar.by_name("graph.json")?; let board = serde_json::from_reader(json_file)?; let image = ar.by_name("image.png").ok(); if image.is_none() { return Ok((board, None)) } let mut image_file = image.unwrap(); let mut buf = Vec::new(); image_file.read_to_end(&mut buf)?; let image = decode_png(&buf); Ok((board, Some(image))) } pub fn encode_png(image: &DynamicImage) -> Vec { let mut cursor = Cursor::new(Vec::new()); image.write_to(&mut cursor, image::ImageOutputFormat::Png).unwrap(); cursor.into_inner() } pub fn decode_png(buf: &[u8]) -> DynamicImage { let cursor = Cursor::new(buf); let mut reader = ImageReader::new(cursor); reader.set_format(image::ImageFormat::Png); reader.decode().unwrap() }