ความคิดเห็นที่ 2
ภาพต้นฉบับมาจากหนังสือ Selected Papers on Computer Science - Donald E Knuth ผมเห็นว่าสวยดีจึงคัดมาให้ชม ระหว่างที่ร่างโปรแกรมหยาบๆก็คิดว่าวิธีวาดไม่มีอะไรซับซ้อน ถ้าเอาโปรแกรมต้นฉบับมาลงพร้อมคำบรรยายนิดหน่อย คนอื่นๆอาจจะเอาไปใช้ประโยชน์ต่อได้
หน้าที่ของโปรแกรมนี้คือสร้างแบบจำลองภาพปักครอสติชไว้บนคอมพิวเตอร์ แล้วส่งออกมาเป็นไฟล์ภาพ
ควรใช้โครงสร้างข้อมูลแบบไหนจึงจะยืดหยุ่นพอรับมือกับภาพปักครอสติชใดๆได้? ใช้เวลาคิดสักสามนาทีคุณจะนึกออกว่า
-ผ้าปักครอสติชนั้นถูกตีตารางไว้แล้ว และ... -ภาพครอสติชจะเสร็จสมบูรณ์เมื่อคุณปักด้ายสีที่เหมาะสมในตำแหน่งที่เหมาะสมตามอย่างต้นฉบับ
เมื่อพูดถึงตารางก็หมายถึงอาร์เรย์สองมิติ เมื่อพูดถึงสีที่เหมาะสมในตำแหน่งที่เหมาะสมก็หมายความว่าในแต่ละช่องของอาร์เรย์สองมิตินั้นต้องเก็บข้อมูลสีของด้าย สรุปว่างานนี้เราใช้อาร์เรย์สองมิติของสีเป็นแบบจำลองแทนภาพปักครอสติชต้นฉบับ
Color[][] cells = new Color[rows][columns];
ปัญหาข้อต่อมาคือจะแปลงภาพต้นฉบับที่เราเห็นให้เป็นอาร์เรย์สองมิติได้อย่างไร
ภาพตัวอย่างที่คุณเห็นนี้มีขนาด 87x87 ช่อง จำนวนช่องที่คุณต้องลงสีทั้งหมดคือ 2410 หากไม่พลิกแพลงบ้างเลย คุณต้องกรอกข้อมูลภาพแบบนี้
cells[2][43] = ELEGANT_BLUE; ...(ช่วงนี้มีคำสั่งแบบเดียวกันแทรกอยู่ 2408 บรรทัด)... cells[84][43] = ELEGANT_BLUE;
นอกจากใช้เวลานานเกินไปแล้ว ยังมีโอกาสผิดพลาดและตรวจแก้ได้ยาก ผมจึงเลือกใช้วิธี encode ภาพต้นฉบับด้วยสตริงของตัวเลขสำหรับแต่ละคอลัมน์ จากซ้ายไปขวา แบบนี้
String encodedColumns = new String[87]; encodedColumns[0] = "87"; encodedColumns[1] = "87"; encodedColumns[2] = "43-1*-43"; ...(ช่วงนี้มีคำสั่งแบบเดียวกันแทรกอยู่ 81 บรรทัด)... encodedColumns[84] = "43-1*-43"; encodedColumns[85] = "87"; encodedColumns[86] = "87";
เล็งจนตาแทบเหล่อยู่หลายชั่วโมงจึงจดมาได้ครบทั้ง 87 คอลัมน์ ยังดีนะเนี่ยมีแค่สีเดียว
แต่ข้อมูลแบบนี้ยังส่งไปวาดโดยตรงไม่ได้ จนกว่าเราจะเอามันมาแปลงเป็นอาร์เรย์สองมิติของสีอย่างที่เราออกแบบไว้แต่แรก สังเกตครึ่งหลังในเมธอด main() แล้วลองนับดูว่า encoding แบบนี้ประหยัดไปได้กี่บรรทัด
เมื่อได้อาร์เรย์สองมิติของสีแล้วก็สร้างอินสแตนซ์ของคลาส CrossStitch ขึ้นมาแล้วจัดการส่งออกมาเป็นไฟล์ภาพในฟอร์แมต GIF เป็นอันเสร็จงาน
new CrossStitch(cells).toGIF(new FileOutputStream("cupid.gif"));
เมธอด toGIF() ทำงานอย่างไร ฝากไว้เป็นการบ้านไปดูต่อเองนะครับ แต่อยากให้สังเกตว่าบางช่องที่ภาพต้นฉบับเว้นไว้เนี่ย เวลาเราจะเว้นตามบ้างเราจะไม่ใส่ข้อมูลสีลงไปในตำแหน่งนั้น นี่หละความหมายและวิธีใช้งาน null ในจาว่า
ถ้าคุณอยากจะเอาโปรแกรมนี้ไปเล่นต่อก็สามารถดัดแปลงโปรแกรมใน main() ได้ตามชอบใจ แก้อย่างไรก็ได้ ขอให้เอาต์พุตออกมาเป็นอาร์เรย์สองมิติของสีเพื่อสร้างอินสแตนซ์ของ CrossStitch ได้เท่านั้น เพื่อให้ง่ายก็ลองเล่นกับภาพสีเดียวตามตัวอย่างก่อน และอย่าให้ภาพมันใหญ่เกินไป เดี๋ยวจะเล็งจนตาเหล่แล้วไม่เสร็จหละแย่เลย
ขั้นต่อไปค่อยหาภาพหลากสีมาแล้วออกแบบ encoding ให้เหมาะกับภาพนั้น แล้วค่อยปรับโปรแกรม main() ตาม encoding ใหม่ ตัวโปรแกรมแก้ไม่ยาก แต่ตอนเล็งหละคุณเอ๋ย... ถือว่าฝึกความมานะละกัน
ลองเอาไปเล่นดู ประหยัดค่าผ้าค่าด้าย จะเอากี่ก็อปปี้ก็ได้ แถมอยู่ค้ำฟ้าด้วยครับ
จากคุณ :
the apprentice paragon - [16 มี.ค. 45 19:10:06]
|
|
|