2009-07-20 41 views
31

Tôi đã có một biểu mẫu với một TImage lớn trên đó làm nền. Vấn đề là, điều này được lưu trữ trực tiếp trong DFM dưới dạng bitmap, chiếm khoảng 3 MB. Tệp PNG gốc là ~ 250K. Tôi muốn cố gắng giảm sưng lên bằng cách nhúng PNG vào tài nguyên, và sau đó có biểu mẫu tải nó trong OnCreate. Tôi có thể làm điều đó ngay bây giờ mà Delphi 2009 bao gồm hỗ trợ PNG, ngoại trừ tôi không hoàn toàn biết làm thế nào để xây dựng một tập tin tài nguyên với một PNG trong đó. Bất cứ ai biết làm thế nào được thực hiện?Làm cách nào để tạo tài nguyên PNG?

Trả lời

50

Ví dụ tập tin văn bản (tên myres.rc):

MYPNG RCDATA mypng.png 

Đã thêm vào dự án:

{$R 'myres.res' 'myres.rc'} 

Ví dụ về tải trong thời gian chạy:

uses 
    PngImage; 

var 
    Png: TPngImage; 
begin 
    Png := TPngImage.Create; 
    try 
    Png.LoadFromResourceName(HInstance, 'MYPNG'); 
    Image1.Picture.Graphic := Png; // Image1: TImage on the form 
    finally 
    Png.Free; 
    end; 
end; 
+0

'RCDATA' có phải là loại tài nguyên cụ thể nhất có sẵn cho loại đồ họa đó không? Chẳng hạn, không có 'RT_PNG'? –

+2

Câu hỏi hay, Rob. SDK nền tảng hiện được cài đặt của tôi là dành cho Windows Server 2003 R2 và tôi không thể tìm thấy một hằng số PNG cụ thể trong WinUser.h. Tôi không chắc chắn, mặc dù. Nó có thể được tuyên bố ở một nơi khác, có lẽ trong một phiên bản sau của Platform SDK. –

+11

LoadFromResourceName đặc biệt tìm kiếm tài nguyên kiểu RCDATA. –

1

Nếu bạn đang sử dụng Delphi 2009, TImage sẽ lưu trữ tệp PNG của bạn dưới dạng PNG vào tệp DFM. DFM sẽ lớn hơn vì nội dung nhị phân của thuộc tính Picture.Data của đối tượng TImage được mã hóa trong DFM dưới dạng văn bản thập lục phân. Nhưng khi DFM được biên dịch vào EXE của bạn, nó được biên dịch thành một tài nguyên nhị phân. Hình ảnh của bạn sau đó sẽ chiếm cùng một không gian bên trong tài nguyên RCDATA của biểu mẫu khi lưu trữ PNG trong tài nguyên RCDATA của nó.

Tôi vừa thử nghiệm điều này bằng cách mở một trong các tệp DFM Delphi 2009 của riêng tôi có thành phần TImage có hình ảnh PNG được tải tại thời điểm thiết kế trong trình chỉnh sửa văn bản, sao chép nội dung của thuộc tính Picture.Data và dán chúng vào trình chỉnh sửa hex. Trình soạn thảo hex cho tôi biết rằng thuộc tính Picture.Data lưu trữ một tệp PNG thực có tiền tố là 10 byte. Byte đầu tiên là $ 09 và 9 byte chính tả tiếp theo là TPngImage. Nếu tôi xóa 10 byte đó và lưu tệp trong trình chỉnh sửa hex, tôi sẽ nhận được tệp PNG thích hợp.

Vì vậy, nếu bạn đang sử dụng Delphi 2009, chỉ cần tải hình ảnh PNG vào thành phần TImage tại thời điểm thiết kế.

+0

Thú vị, nhưng về trường hợp hình ảnh được tái sử dụng trên nhiều biểu mẫu? Delphi có đủ thông minh để lưu trữ chỉ một bản sao, hay nó lưu trữ hình ảnh n lần, trong đó n là số lượng thành phần TImage với hình ảnh đó được tải? :) – Drarok

+3

Mỗi thành phần TImage lưu hình ảnh của nó độc lập với mọi phiên bản TImage khác.Vì vậy, nếu bạn tải cùng một hình ảnh vào n trường hợp của TImage, cùng một hình ảnh được lưu trữ n lần. Một cách để giải quyết vấn đề này là sử dụng mẫu thừa kế. Tạo một mẫu cơ sở với TImage và tải hình ảnh vào đó. Sau đó, lấy tất cả các biểu mẫu cần có cùng một TImage từ biểu mẫu đó. Bất kỳ thuộc tính nào không được thay đổi trong biểu mẫu con cháu chỉ được lưu trữ trong DFM của biểu mẫu tổ tiên. Điều đó bao gồm dữ liệu hình ảnh của một TImage. –

2

Đối với những người sử dụng C++ Builder mã này làm việc cho tôi:

Trong ResourceTest.rc nộp

IMG_BMP BITMAP "Ressources\\myimage.bmp"; 
IMG_PNG RCDATA "Ressources\\myimage.png"; 

Trong tập tin ResourceTest.rh

#ifndef ResourceTestRH 
#define ResourceTestRH 

#define IMG_BMP "IMG_BMP" 
#define IMG_PNG "IMG_PNG" 

#endif 

Trong tệp ResourceTest.cpp

#include "pngimage.hpp" 

// Loading bmp image from resource 
Graphics::TBitmap *bmpImage = new Graphics::TBitmap(); 
bmpImage->LoadFromResourceName((int)HInstance, IMG_BMP); 

// Loading png image from resource 
TPngImage *pngImage = new TPngImage(); 
pngImage->LoadFromResourceName((int)HInstance, IMG_PNG); 
Các vấn đề liên quan