PDF Library for Delphi chấp nhận hình ảnh AVIF, HEIF và JPEG XL làm đầu vào thông qua AddModernImageFromFile cùng các biến thể stream và chuỗi của nó, giữ lại kênh alpha, hồ sơ ICC đã nhúng và kênh 16-bit trên đường vào đối tượng hình ảnh PDF. Việc phát hiện định dạng diễn ra qua một lượt đọc magic-number bị giới hạn, và việc giải mã chạy qua một backend có thể thay thế, nên không có gì bên ngoài bị gọi đối với một file thực ra không phải là một trong các định dạng đó
Những định dạng này bước vào các quy trình tài liệu thông qua điện thoại. iOS đã tạo ra HEIC theo mặc định trong nhiều năm, thiết bị Android tạo ra AVIF, và một kỹ thuật viên hiện trường chụp ảnh một bộ phận hỏng gửi đi một hình ảnh mà một bộ tạo báo cáo PDF được xây dựng năm 2015 hoàn toàn không thể mở được. Đường xử lý dự phòng chung, giải mã qua một bitmap nền tảng, thường xuyên cho ra màu 8-bit và làm mất kênh alpha lẫn hồ sơ màu trên đường đi
Đường xử lý hình ảnh hiện đại giữ lại những gì mà một phép chuyển đổi bitmap làm mất?
Ba thứ, và mỗi thứ đều có một quy trình phụ thuộc vào nó. Alpha được giữ lại, quan trọng đối với logo và ảnh cắt sản phẩm được ghép lên trên nội dung trang. Hồ sơ ICC được giữ lại, quan trọng đối với bất cứ thứ gì sẽ được in hoặc khớp màu. Và kênh 16-bit được giữ lại, quan trọng đối với hình ảnh y tế và khoa học nơi lượng tử hóa 8-bit phá hủy chính những dải chuyển sắc mà hình ảnh được chụp để ghi lại
Cho một hình ảnh đi qua một bitmap nền tảng làm mất cả ba trong một bước, và nó làm vậy một cách âm thầm: file PDF kết quả trông gần đúng, và không ai nhận ra cho đến khi một máy in hỏi vì sao màu đỏ thương hiệu lại sai. Giá trị tùy chọn 8 trên các lệnh gọi hình ảnh hiện đại là cờ giữ alpha, ICC và kênh 16-bit đi cùng nhau, và đó là giá trị mặc định cho các lệnh gọi đó
Thêm một hình ảnh vào trang
Lệnh gọi trả về một định danh hình ảnh, sau đó được chọn và vẽ, hoặc vẽ rồi giải phóng trong một bước:
uses
PDFlibrary, PDFlibModernImage;
var
Lib: TPDFlib;
ImageID: Integer;
begin
Lib := TPDFlib.Create;
try
Lib.NewDocument;
Lib.SetPageSize('A4');
Lib.NewPage;
// Options = 8 giữ lại alpha, ICC và kênh 16-bit
ImageID := Lib.AddModernImageFromFile('site-photo.heic', 8);
if ImageID > 0 then
Lib.DrawImageAndRelease(ImageID, 40, 40, 515, 340)
else
Lib.DrawText(40, 40, 'image could not be decoded');
Lib.SaveToFile('inspection-report.pdf');
finally
Lib.Free;
end;
end;
Việc phát hiện diễn ra trước khi giải mã và cố tình được giữ hẹp. Thư viện đọc một header bị giới hạn, nhận diện các nhãn hiệu định dạng file media cơ sở ISO xác định AVIF và HEIF, và nhận diện cả chữ ký thô lẫn chữ ký container của JPEG XL, rồi khôi phục vị trí luồng của bên gọi. Một đầu vào không xác định hoặc bị ngụy trang không bao giờ đến được codec bên ngoài, điều này ngăn một file thực thi được đổi tên bị trao cho một bộ giải mã như thể nó là một hình ảnh
Việc giải mã thực sự diễn ra ở đâu?
Các định dạng hình ảnh hiện đại là những codec lớn, phức tạp, và đưa một cái vào bên trong một thư viện PDF sẽ là một lựa chọn thiết kế kỳ lạ. Backend mặc định nạp động một module MagickWand có thể triển khai ngay trong tiến trình và tìm kiếm nó theo một thứ tự đã được ghi lại: một file hoặc thư mục tường minh bạn đặt, biến môi trường, thư mục file thực thi, và đường dẫn tìm kiếm hệ thống
Các ứng dụng đã đóng gói sẵn một bộ giải mã, hoặc không được phép nạp bất kỳ module bên ngoài nào, thay vào đó đăng ký callback của riêng mình. Hợp đồng rất nhỏ: đọc luồng đầu vào, ghi một PNG ra luồng đầu ra, tôn trọng hướng xoay được yêu cầu:
function MyDecoder(InStream, OutPNG: TStream;
ImageFormat: TPDFlibModernImageFormat;
ApplyOrientation: Boolean): Boolean;
begin
// Giải mã InStream bằng codec của riêng bạn và ghi byte PNG ra OutPNG
Result := DecodeWithBundledCodec(InStream, OutPNG,
ImageFormat, ApplyOrientation);
end;
begin
RegisterModernImageDecoderBackend(MyDecoder);
// ... thêm hình ảnh ...
ClearModernImageDecoderBackend; // quay về backend mặc định
end;
Việc triển khai nhận được một tiện lợi và một sự kiềm chế có chủ đích. Nếu thư mục codec chứa một thư mục con modules\coders, thư viện tự điền các biến môi trường codec mà bố cục đó cần, nhưng chỉ khi ứng dụng chủ chưa tự đặt chúng. Một ứng dụng có chiến lược triển khai runtime riêng vẫn giữ nguyên chiến lược đó
Vì sao lại đi qua PNG ở giữa?
Bắc cầu qua một PNG trong bộ nhớ thay vì một bộ đệm điểm ảnh thô trông như một bước thừa và thực ra lại là bước rẻ nhất mà vẫn đúng. PNG biểu diễn mọi thứ cần phải sống sót, alpha, kiểu màu, độ sâu bit và một hồ sơ ICC nhúng, và thư viện đã có sẵn một đường dẫn trưởng thành, được kiểm thử kỹ từ PNG vào một đối tượng hình ảnh PDF với đúng bộ lọc và không gian màu. Tái sử dụng nó nghĩa là các định dạng hiện đại kế thừa nhiều năm công sức đảm bảo tính đúng đắn thay vì có một triển khai song song riêng
Cầu nối này hoàn toàn nằm trong bộ nhớ, nên không có file tạm nào được tạo ra và không cần dọn dẹp khi crash. Một nếp gấp cần được xử lý tường minh: một số phép chuyển đổi làm mất hồ sơ ICC khi đổi định dạng. Vì vậy backend chụp lại hồ sơ nguồn trước khi chuyển định dạng, nén nó bằng Flate, dựng một khối iCCP hợp lệ với CRC được tính lại, và loại bỏ bất kỳ khối sRGB nào có thể xung đột với nó. Trong thử nghiệm, một file AVIF đã giải mã giữ được RGBA 16-bit với alpha 16-bit, và hồ sơ được trích xuất từ file PDF kết quả khớp byte theo byte với hồ sơ nguồn ở 60.960 byte
Lưu ý thực tế trước khi bật tính năng này trong sản xuất
Hãy kiểm tra tính khả dụng lúc khởi động thay vì tại bức ảnh đầu tiên. ModernImageCodecAvailable báo cáo liệu một backend có thể được dùng hay không, và SetModernImageCodecLibrary trỏ đến một file hoặc thư mục tường minh khi việc triển khai của bạn đặt codec ở một nơi không chuẩn:
Lib.SetModernImageCodecLibrary('C:\MyApp\codecs');
if Lib.ModernImageCodecAvailable = 0 then
Log('modern image input unavailable - HEIC and AVIF will be refused');
Hãy theo dõi dung lượng file của kết quả. Một hình ảnh RGBA 16-bit với hồ sơ nhúng là một đối tượng hình ảnh PDF lớn, và một báo cáo có bốn mươi hình ảnh như vậy sẽ có dung lượng lớn. Khi tài liệu hướng đến việc xem trên màn hình thay vì in ấn, giảm mẫu (downsampling) trước khi nhúng là đánh đổi đúng đắn, và các đòn bẩy dung lượng tổng quát được đề cập trong tối ưu hóa dung lượng file PDF
Cuối cùng, hãy quyết định chính sách màu sắc một cách có chủ đích. Giữ hồ sơ nguồn là đúng đắn cho công việc lưu trữ và in ấn; chuyển sang một không gian màu chung cho toàn tài liệu là đúng đắn khi một tập hợp ảnh chụp hỗn tạp cần trông đồng nhất, và đường chuyển đổi được mô tả trong đổi màu tài liệu sang không gian màu khác. Nếu bạn cần xác nhận thứ gì thực sự đã vào file, đường kiểm tra trong trích xuất văn bản, hình ảnh và font báo cáo các đối tượng hình ảnh mà một tài liệu mang theo
Đầu vào hình ảnh hiện đại, quản lý màu sắc và tối ưu hóa hình ảnh là một phần của cùng một thư viện cho Delphi, C++Builder và Free Pascal; danh sách tính năng đầy đủ có trên trang PDF Library for Delphi