مقاله فنی

تعبیه تصاویر AVIF، HEIF و JPEG XL در PDF از دلفی

PDF Library for Delphi تصاویر AVIF، HEIF و JPEG XL را به‌عنوان ورودی از طریق AddModernImageFromFile و گونه‌های جریانی و رشته‌ای آن می‌پذیرد، و آلفا، پروفایل ICC تعبیه‌شده و کانال‌های ۱۶بیتی را در راه ورود به شیء تصویر PDF حفظ می‌کند. تشخیص قالب روی یک خواندن کران‌دار عدد جادویی رخ می‌دهد، و رمزگشایی از طریق یک باطن قابل‌جایگزینی اجرا می‌شود، بنابراین برای فایلی که واقعاً یکی از آن قالب‌ها نیست، هیچ چیز خارجی فراخوانی نمی‌شود

این قالب‌ها از طریق گوشی‌ها وارد جریان‌کارهای سند شدند. iOS سال‌هاست به‌طور پیش‌فرض HEIC تولید کرده، دستگاه‌های اندروید AVIF تولید می‌کنند، و یک تکنسین میدانی که از یک قطعه آسیب‌دیده عکس می‌گیرد تصویری ارسال می‌کند که یک موتور تولید گزارش PDF که در سال ۲۰۱۵ ساخته شده اصلاً نمی‌تواند باز کند. مسیر بازگشتی عمومی، رمزگشایی از طریق یک بیت‌مپ سکو (platform)، به‌طور قابل‌اتکا رنگ ۸بیتی تولید می‌کند و آلفا و پروفایل رنگ را در این مسیر از دست می‌دهد

مسیر تصویر مدرن چه چیزی را حفظ می‌کند که یک تبدیل بیت‌مپی از دست می‌دهد؟

سه چیز، و هرکدام جریان‌کاری دارند که به آن وابسته است. آلفا زنده می‌ماند، که برای لوگوها و برش‌های محصولی که روی محتوای صفحه ترکیب می‌شوند اهمیت دارد. پروفایل ICC زنده می‌ماند، که برای هر چیزی که چاپ یا رنگ‌تطبیق خواهد شد اهمیت دارد. و کانال‌های ۱۶بیتی زنده می‌مانند، که برای تصویربرداری پزشکی و علمی که در آن‌ها کوانتیزاسیون ۸بیتی همان تدریج‌هایی را که تصویر برای آن‌ها ثبت شده نابود می‌کند، اهمیت دارد

عبوردادن یک تصویر از یک بیت‌مپ سکو هر سه را در یک گام از دست می‌دهد، و این کار را به‌طور خاموش انجام می‌دهد: PDF نتیجه‌شده تقریباً درست به نظر می‌رسد، و هیچ‌کس متوجه نمی‌شود تا زمانی که یک چاپگر بپرسد چرا قرمز شرکتی نادرست است. مقدار گزینه ۸ در فراخوانی‌های تصویر مدرن، پرچمی است که آلفا، ICC و کانال‌های ۱۶بیتی را با هم نگه می‌دارد، و پیش‌فرض همان فراخوانی‌هاست

افزودن یکی به یک صفحه

این فراخوانی یک شناسه تصویر برمی‌گرداند، که سپس انتخاب و ترسیم می‌شود، یا در یک گام ترسیم و آزاد می‌شود:

uses
  PDFlibrary, PDFlibModernImage;

var
  Lib: TPDFlib;
  ImageID: Integer;
begin
  Lib := TPDFlib.Create;
  try
    Lib.NewDocument;
    Lib.SetPageSize('A4');
    Lib.NewPage;

    // Options = 8 آلفا، ICC و کانال‌های ۱۶بیتی را نگه می‌دارد
    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;

تشخیص، مقدم بر رمزگشایی است و به‌عمد باریک است. کتابخانه یک سربرگ کران‌دار می‌خواند، برندهای قالب فایل رسانه پایه ISO را که AVIF و HEIF را شناسایی می‌کنند تشخیص می‌دهد، و هم امضاهای خام و هم امضاهای ظرف JPEG XL را تشخیص می‌دهد، سپس موقعیت جریان فراخوان را بازمی‌گرداند. یک ورودی ناشناخته یا استتارشده هرگز به کدک خارجی نمی‌رسد، که از تحویل یک فایل اجرایی تغییرنام‌یافته به یک رمزگشا، انگار که یک تصویر باشد، جلوگیری می‌کند

رمزگشایی واقعاً کجا رخ می‌دهد؟

قالب‌های تصویر مدرن، کدک‌های بزرگ و پیچیده‌ای هستند، و گذاشتن یکی از آن‌ها درون یک کتابخانه PDF یک انتخاب طراحی عجیب خواهد بود. باطن پیش‌فرض یک ماژول قابل‌استقرار MagickWand را به‌صورت درون‌فرایندی به‌طور پویا بارگذاری می‌کند و آن را به یک ترتیب مستندشده جست‌وجو می‌کند: یک فایل یا دایرکتوری صریح که شما تنظیم می‌کنید، متغیرهای محیطی، دایرکتوری فایل اجرایی، و مسیر جست‌وجوی سیستم

برنامه‌هایی که از قبل یک رمزگشا عرضه می‌کنند، یا که اصلاً نباید یک ماژول خارجی بارگذاری کنند، به‌جای آن فراخوانی برگشتی مخصوص خودشان را ثبت می‌کنند. قرارداد کوچک است: جریان ورودی را بخوان، یک PNG را در جریان خروجی بنویس، جهت‌گیری درخواستی را رعایت کن:

function MyDecoder(InStream, OutPNG: TStream;
  ImageFormat: TPDFlibModernImageFormat;
  ApplyOrientation: Boolean): Boolean;
begin
  // InStream را با کدک مخصوص خود رمزگشایی کن و بایت‌های PNG را در OutPNG بنویس
  Result := DecodeWithBundledCodec(InStream, OutPNG,
    ImageFormat, ApplyOrientation);
end;

begin
  RegisterModernImageDecoderBackend(MyDecoder);
  // ... افزودن تصاویر ...
  ClearModernImageDecoderBackend;    // بازگشت به باطن پیش‌فرض
end;

استقرار یک راحتی و یک خویشتن‌داری عمدی می‌گیرد. اگر دایرکتوری کدک یک زیردایرکتوری modules\coders داشته باشد، کتابخانه متغیرهای محیطی کدکی را که چنین چیدمانی به آن‌ها نیاز دارد پر می‌کند، اما فقط وقتی برنامه میزبان از قبل آن‌ها را تنظیم نکرده باشد. برنامه‌ای با استراتژی استقرار زمان‌اجرای خودش، آن را نگه می‌دارد

چرا PNG در میانه؟

پل‌زدن از طریق یک PNG درون‌حافظه‌ای به‌جای یک بافر پیکسلی خام، مثل یک گام اضافی به نظر می‌رسد و در واقع ارزان‌ترین گام درست است. PNG هر چیزی را که باید زنده بماند بیان می‌کند، آلفا، نوع رنگ، عمق بیت و یک پروفایل ICC تعبیه‌شده، و کتابخانه از قبل یک مسیر بالغ و به‌خوبی آزمایش‌شده از PNG به یک شیء تصویر PDF با فیلترها و فضای رنگی درست دارد. استفاده مجدد از آن یعنی قالب‌های مدرن سال‌ها کار درستی به ارث می‌برند به‌جای گرفتن یک پیاده‌سازی موازی

پل کاملاً درون حافظه است، بنابراین هیچ فایل موقتی ساخته نمی‌شود و هیچ پاک‌سازی‌ای در هنگام خرابی لازم نیست. یک چین‌خوردگی به رسیدگی صریح نیاز داشت: برخی تبدیل‌ها پروفایل ICC را هنگام تغییر قالب کنار می‌گذارند. بنابراین باطن پروفایل منبع را پیش از تعویض قالب می‌گیرد، آن را با Flate فشرده می‌کند، یک تکه iCCP معتبر با یک CRC دوباره‌محاسبه‌شده می‌سازد، و هر تکه sRGBای را که با آن تداخل می‌کرد حذف می‌کند. در آزمایش، یک AVIF رمزگشایی‌شده RGBA ۱۶بیتی با آلفای ۱۶بیتی را نگه داشت، و پروفایلی که از PDF نتیجه‌شده استخراج شد در ۶۰٬۹۶۰ بایت بیت به بیت با پروفایل منبع مطابقت داشت

نکات عملی پیش از فعال‌کردن آن در تولید

در راه‌اندازی در دسترس‌بودن را بررسی کنید نه در اولین عکس. ModernImageCodecAvailable گزارش می‌دهد آیا یک باطن می‌تواند استفاده شود، و SetModernImageCodecLibrary به یک فایل یا دایرکتوری صریح اشاره می‌کند وقتی استقرار شما کدک را در جایی غیراستاندارد قرار می‌دهد:

Lib.SetModernImageCodecLibrary('C:\MyApp\codecs');
if Lib.ModernImageCodecAvailable = 0 then
  Log('modern image input unavailable - HEIC and AVIF will be refused');

حجم فایل نتیجه را زیر نظر بگیرید. یک تصویر RGBA ۱۶بیتی با یک پروفایل تعبیه‌شده یک شیء تصویر PDF بزرگ است، و گزارشی با چهل تای آن‌ها بزرگ خواهد بود. وقتی سند برای نمایش روی صفحه‌نمایش مقصد است نه چاپ، کاهش نمونه‌برداری پیش از تعبیه، معاوضه درست است، و اهرم‌های اندازه عمومی در بهینه‌سازی حجم فایل PDF پوشش داده شده

در آخر، خط‌مشی رنگ را به‌عمد تصمیم بگیرید. نگه‌داشتن پروفایل منبع برای کار بایگانی و چاپ درست است؛ تبدیل به یک فضای سراسر-سند وقتی مجموعه‌ای مختلط از عکس‌ها باید یکدست به نظر برسند درست است، و مسیر تبدیل در تغییر رنگ یک سند به یک فضای رنگی دیگر شرح داده شده. اگر نیاز دارید تأیید کنید واقعاً چه چیزی در فایل نشسته، مسیر بازرسی در استخراج متن، تصویر و فونت اشیای تصویری‌ای را که یک سند حمل می‌کند گزارش می‌دهد

ورودی تصویر مدرن، مدیریت رنگ و بهینه‌سازی تصویر بخشی از یک کتابخانه واحد برای دلفی، C++Builder و Free Pascal هستند؛ فهرست کامل ویژگی‌ها در صفحه PDF Library for Delphi قرار دارد