บันทึกรายการรูปภาพใน Delphi
ผู้เขียน:Eve Cole
เวลาอัปเดต:2025-02-03 12:00:04
เมื่อเร็วๆ นี้ ขณะทำงานในโครงการ ฉันพบสถานการณ์ในการบันทึกชุดรูปภาพในรายการรูปภาพ (TImageList) ลงในไฟล์ที่ระบุหรือสตรีมไบนารี เพื่อให้สามารถกู้คืนรูปภาพเหล่านั้นได้แบบไดนามิกเมื่อจำเป็น ดังนั้นฉันจึงค้นหาคุณสมบัติและวิธีการที่เกี่ยวข้องกับคลาส TImageList ในความช่วยเหลือของ Delphi น่าเสียดายที่ Delphi ไม่ได้จัดเตรียมวิธีการ SaveToFile และ SaveToStream ใน TImageList ดังนั้นเมื่อพิจารณาถึงข้อจำกัดปัจจุบันของ TImageList จะต้องใช้วิธีการอื่นเพื่อขยาย ฟังก์ชั่นของ TImageList เพื่อตอบสนองความต้องการของโครงการจริง |
ใช้ฟังก์ชัน API ImageList_Write และ ImageList_Read ทั้งสองจำเป็นต้องระบุพารามิเตอร์ประเภท IStream ฟังก์ชั่นของอันแรกคือการบันทึกรายการรูปภาพของหมายเลขอ้างอิงที่ระบุลงในสตรีมไบนารีของประเภท IStream; . และส่งคืนหมายเลขอ้างอิงให้กับรายการรูปภาพนี้ IStream เป็นวัตถุ OLE และการประกาศใน Delphi คือ TStreamAdapter = class (TInterfacedObject, IStream) ซึ่งหมายความว่า TStreamAdapter เป็นวัตถุที่สืบทอดมาจาก TInterfacedObject ที่จัดการอินเทอร์เฟซ IStream ผ่านวัตถุ TStreamAdapter คุณสามารถรับรู้การจัดการวัตถุอินเทอร์เฟซ IStream โดยวัตถุ TStream ภายในของ Delphi |
สืบทอดคลาสย่อย TImageListEx จาก TImageList และใช้วิธีการ SaveToFileEx และ SaveToStreamEx แบบกำหนดเอง ตามค่าเริ่มต้น รูปภาพที่บันทึกใน TImageList จะประกอบด้วยรูปภาพธรรมดาและรูปภาพมาส์ก ดังนั้น GetImages(Index: Integer; Image, Mask: จัดทำโดยส่วนที่ PRotected ของคลาสพื้นฐาน TCustomImageList จะต้องถูกเรียก) TBitmap) เพื่อรับบิตแมปด้วยหมายเลขดัชนีที่ระบุในรายการรูปภาพและบิตแมปของมาสก์ จากนั้นบันทึกลงในไฟล์แบบกำหนดเองหรือกระแสข้อมูลไบนารีตามลำดับ นอกจากนี้ จำเป็นต้องจัดเตรียมวิธีการ LoadFromFileEx และ LoadFromStreamEx เพื่อรับ บิตแมปจากไฟล์ที่กำหนดเองหรือสตรีมไบนารี |
ตัวควบคุม TImageListEx แบบกำหนดเองสรุปวิธีการสองวิธีข้างต้นในส่วนสาธารณะ |
ซอร์สโค้ดของคลาส TImageListEx เป็นดังนี้: |
ใช้ Windows, SysUtils, คลาส, กราฟิก, การควบคุม, Commctrl, ImgList, Consts; |
TImageListEx = คลาส (TImageList) |
ขั้นตอน LoadFromFile(const FileName: string);//ใช้วิธี API เพื่อบันทึก |
ขั้นตอน LoadFromStream (สตรีม: TStream); |
ขั้นตอน SaveToFile (const FileName: string); |
ขั้นตอน SaveToStream (สตรีม: TStream); |
ขั้นตอน LoadFromFileEx (const FileName: string); // บรรลุวิธีการบันทึกแบบกำหนดเอง |
ขั้นตอน LoadFromStreamEx (สตรีม: TStream); |
ขั้นตอน SaveToFileEx (const FileName: string); |
ขั้นตอน SaveToStreamEx (สตรีม: TStream); |
RegisterComponents('ImageListEx', [TImageListEx]); |
ขั้นตอน TImageListEx.LoadFromFile (const FileName: string); |
สตรีม := TFileStream.Create(ชื่อไฟล์, fmOpenRead); |
ขั้นตอน TImageListEx.LoadFromFileEx (const FileName: string); |
สตรีม := TFileStream.Create(ชื่อไฟล์, fmOpenRead); |
LoadFromStreamEx (สตรีม); |
ขั้นตอน TImageListEx.LoadFromStream (สตรีม: TStream); |
SA := TStreamAdapter.Create (สตรีม); |
หมายเลขอ้างอิง := ImageList_Read(SA); //ชี้หมายเลขอ้างอิงของรายการรูปภาพปัจจุบันไปยังหมายเลขอ้างอิงที่ได้รับจากสตรีมไบนารี |
เพิ่ม EReadError.CreateRes(@SImageReadFail); |
ขั้นตอน TImageListEx.LoadFromStreamEx (สตรีม: TStream); |
ความกว้าง ความสูง: จำนวนเต็ม; |
BinStream: TMemoryStream; |
ขั้นตอน LoadImageFromStream (รูปภาพ: TBitmap); |
Stream.ReadBuffer(Count, SizeOf(Count));//ขั้นแรกให้อ่านขนาดของบิตแมป |
BinStream.CopyFrom(Stream, Count);//จากนั้นอ่านบิตแมป |
BinStream.Position := 0; //รีเซ็ตตัวชี้สตรีม |
รูปภาพ. LoadFromStream (BinStream); |
Stream.ReadBuffer (ความสูง, SizeOf (ความสูง)); |
Stream.ReadBuffer (กว้าง SizeOf (กว้าง)); |
Self.Width := width;//คืนค่าความสูงและความกว้างเดิมของรายการรูปภาพ |
บิตแมป := TBitmap.Create; |
หน้ากาก := TBitmap.Create; |
BinStream := TMemoryStream.Create; |
ในขณะที่ Stream.Position <> Stream.Size ทำ |
LoadImageFromStream(Bitmap);//อ่านบิตแมปจากไบนารีสตรีม |
LoadImageFromStream(Mask);//อ่านบิตแมปมาส์กจากสตรีมไบนารี |
เพิ่ม(บิตแมป, มาสก์);//เพิ่มบิตแมปและบิตแมปมาส์กของมันในรายการรูปภาพ |
ขั้นตอน TImageListEx.SaveToFile (const FileName: string); |
สตรีม := TFileStream.Create(ชื่อไฟล์, fmCreate); |
ขั้นตอน TImageListEx.SaveToFileEx (const FileName: string); |
สตรีม := TFileStream.Create(ชื่อไฟล์, fmCreate); |
ขั้นตอน TImageListEx.SaveToStream (สตรีม: TStream); |
SA := TStreamAdapter.Create (สตรีม); |
ถ้าไม่ใช่ ImageList_Write(Handle, SA) แล้ว//บันทึกรายการรูปภาพปัจจุบันลงในสตรีมไบนารี |
เพิ่ม EWriteError.CreateRes(@SImageWriteFail); |
ขั้นตอน TImageListEx.SaveToStreamEx (สตรีม: TStream); |
ความกว้าง ความสูง: จำนวนเต็ม; |
BinStream: TMemoryStream; |
ขั้นตอน SetImage (รูปภาพ: TBitmap; IsMask: บูลีน); |
Image.Assign(nil);//ล้างรูปภาพที่บันทึกไว้ล่าสุดเพื่อหลีกเลี่ยงไม่ให้รูปภาพซ้อนทับกัน |
ถ้า IsMask แล้ว MonoChrome := True;//บิตแมปมาส์กต้องใช้ขาวดำ |
ความกว้าง := ความกว้างของตัวเอง; |
ขั้นตอน SaveImageToStream (รูปภาพ: TBitmap); |
รูปภาพ SaveToStream (BinStream); |
Stream.WriteBuffer(Count, SizeOf(Count));//ขั้นแรกให้บันทึกขนาดของบิตแมป |
Stream.CopyFrom(BinStream, 0);//จากนั้นให้บันทึกบิตแมป |
ความกว้าง := ความกว้างของตัวเอง; |
Stream.WriteBuffer(Height, SizeOf(Height));//บันทึกความสูงของรายการรูปภาพต้นฉบับ |
Stream.WriteBuffer(Width, SizeOf(Width));//บันทึกความกว้างของรายการรูปภาพต้นฉบับ |
บิตแมป := TBitmap.Create; |
หน้ากาก := TBitmap.Create; |
BinStream := TMemoryStream.Create; |
สำหรับ I := 0 ถึงนับ - 1 do//บันทึกรูปภาพในรายการรูปภาพ |
GetImages(I, Bitmap, Mask);//รับบิตแมปที่มีหมายเลขดัชนีที่ระบุและบิตแมปมาส์ก |
SaveImageToStream(Bitmap);//บันทึกบิตแมปไปยังไบนารีสตรีม |
SaveImageToStream(Mask);//บันทึกบิตแมปมาส์กลงในสตรีมไบนารี |
ข้อมูลต่อไปนี้สาธิตวิธีการใช้งานใน Delphi: |
ขั้นแรกให้สร้างโครงการใหม่ใน Delphi จากนั้นวางตัวควบคุม ImageListEx ตัวควบคุม TreeView และตัวควบคุมปุ่มสี่ปุ่มบน Form1 เชื่อมโยงคุณสมบัติรูปภาพของตัวควบคุม TreeView กับ ImageListEx เพิ่มรูปภาพจำนวนเท่าใดก็ได้ลงใน ImageListEx และเพิ่มจำนวนรายการที่สอดคล้องกันลงใน TreeView คุณสมบัติ ImageIndex ของรายการสอดคล้องกับหมายเลขดัชนีของรูปภาพใน ImageListEx ขณะนี้ไอคอนที่เกี่ยวข้องสามารถแสดงก่อนแต่ละรายการใน TreeView ได้ |
สุดท้ายนี้ เขียนในเหตุการณ์ OnClick ของ Button1: |
ImageListEx1.SaveToFile('C:CJ.dat'); |
ImageListEx1.SaveToFileEx('C:CJEx.dat'); |
ในเหตุการณ์ OnClick ของ Button2 เขียน: ImageListEx1.Clear; |
เขียนในเหตุการณ์ OnClick ของ Button3: ImageListEx1.LoadFromFile('C:CJ.dat'); |
เขียนในเหตุการณ์ OnClick ของ Button4: ImageListEx1.LoadFromFileEx('C:CJEx.dat'); |
เรียกใช้โปรแกรม ขั้นแรกให้คลิก Button1 จากนั้นคลิก Button2 และสุดท้ายให้คลิก Button3 หรือ Button4 คุณจะเห็นว่าโปรแกรมสามารถบันทึกรูปภาพในรายการรูปภาพไปยังไฟล์ที่ระบุ และสามารถกู้คืนและแสดงรูปภาพเหล่านั้นจากไฟล์ที่ระบุได้อย่างถูกต้อง . |
เนื้อหาที่แนะนำในบทความนี้ถูกนำมาใช้เพื่อแก้ไขสถานการณ์ที่ฉันพบในโครงการจริง ฉันหวังว่าโปรแกรมเมอร์ที่ประสบปัญหานี้สามารถหาคำตอบได้ รหัสข้างต้นผ่านการดีบักและทำงานใน Delphi5.0 และ Windows2000 Server |