บันทึกผลการทดลอง แสดงภาพ Jpeg ในขณะที่ยังโหลดไม่เสร็จ เพื่อแสดงภาพแบบ Progressive Jpeg เพื่อให้ผู้ใช้งานเห็นภาพร่างก่อนที่ภาพจะโหลดมาเสร็จสมบูรณ์
หากเราเอาข้อมูลภาพ Jpeg ที่โหลดมาแต่ยังไม่เสร็จมาแสดงใน Widget ผลที่ได้คือ Exception Error ที่แจ้งว่า ImageException: Invalid progressive encoding หลังจากพยายามหาวิธีการโดยใช้ dependencies ที่มีพบว่า
หลังจากลองพยายามใช้ตัว ImageProvider ของ Flutter และ image สรุปว่าไม่เจอทางออกว่าจะทำยังไงก็ปัญหาตรงนี้ดี จากการศึกษารูปแบบของไฟล์ Jpeg พบว่าเมื่อจบไฟล์จะมีข้อมูล 2 byte คือ 0xFF และ 0xD9 เพื่อบอกว่าเป็น End of Image
เพื่อบอกตัวถอดรหัสภาพ Jpeg ว่าข้อมูลภาพจบแล้ว แม้ว่าภาพจะไม่สมบูรณ์ก็ตาม เลยลองใส่ข้อมูล EOI ต่อท้ายเข้าไป ผลที่ได้คือตัวถอดรหัสสามารถถอดรหัสภาพที่มีได้ และสามารถเอาข้อมูลดังกว่ามาแสดงบนหน้าจอได้
ในตัวอย่าง ได้ลองทำไฟล์ test.jpg ขึ้นมา แล้วลองนำบางส่วนของไฟล์มาแสดง โดยทำการเพิ่ม EOI ต่อท้ายเข้าไป
int testPercent = 30; // test load only 30% of jpeg image file
File jpeg = File('D:\\test.jpg');
Uint8List content = jpeg.readAsBytesSync();
int lengthTest = ((content.length / 100) * testPercent).truncate(); // calculate size of content
Uint8List jpegContext = Uint8List.fromList([...content.sublist(0, lengthTest), 0xFF, 0xD9]); // add EOI after jpeg data
MemoryImage? outputImage; // ImageProvider for Image() widget
try {
outputImage = MemoryImage(jpegContext);
setState(() {
debugPrint('size of jpeg is ${jpegContext!.length}, $testPercent');
});
} catch (e) {
outputImage = null;
}
ในส่วนของการแสดงภาพ ใช้ Image widget ธรรมดาแสดงภาพ
if(outputImage != null) {
Image(image: outputImage!, gaplessPlayback: true);
}
เนื่องจากต้องการ update ภาพทุกครั้งที่มีข้อมูลใหม่มาจากอินเทอร์เน็ต ก็ให้กำหนด gaplessPlayback เป็น true เพื่อให้ค้างภาพเดิมไว้แล้วเขียนภาพใหม่ทับ
เนื่องจากการเพิ่ม EOI เข้าไปต่อท้ายเป็นการแก้ไขแบบ hack ซึ่งไม่ใช่วิธีที่ถูกต้อง และอาจทำให้บางครั้งตัวถอดรหัสภาพไม่สามารถถอดรหัสภาพได้ ดังนั้นอย่าลืมใช้ try catch เพื่อจัดการปัญหาเมื่อถอดรหัสไม่ได้ด้วย ซึ่งจากที่ใช้อยู่ก็คือหากถอดรหัสไม่ได้ก็ไม่ไป update ตัว Image widget และรอข้อมูลมาเพิ่มแล้วลองใหม่ หากไม่เกิด error ก็แสดงภาพที่โหลดมาได้ตามปกติ