Teknik Makale

PDF Rendering'de Blend Modlu Gruplar ve Luminosity Maskeleri

HotPDF, Normal dışı bir blend moduyla boyanmış bir PDF transparency grubunu, grubun kendi blend'ini hesaplamasına izin vererek render eder: izlediği ya da siyah ile beyaz geçişlerinden kurtardığı grup alfasını kullanarak Cb(1 − α) + α·B(Cb, Cs). v2.770.0'den itibaren THotPDF.RenderColorimetricLuminosityMasks özelliği ayrıca luminosity soft masklerin rengi, yaygın görüntüleyiciler gibi ağırlıklı RGB olarak mı yoksa ISO 32000-1'in anlattığı gibi CIE Y olarak mı okuyacağını seçer

İki değişiklik de aynı türden bir dosyadan çıktı: bir tasarım aracından dışa aktarılmış, ürün fotoğrafının yumuşak bir drop shadow üzerinde durduğu bir sayfa. Gölge, /BM /Multiply ile bir transparency grubu olarak çizilen bir Form XObject'tir ve solması bir luminosity soft mask'tir. Diğer görüntüleyicilerde gölge açık, nötr bir gridir. Eski HotPDF sürümlerinde neredeyse siyah çıkıyor ve arka plan rengine doğru boyanıyordu. Birbirinin üstüne yığılmış iki ayrı hata vardı ve ikisini de açıp incelemeye değer; çünkü "önce opak nesneler" tasarımından büyüyen her render motoru ikisine de çarpar

Bir Multiply drop shadow neden çok koyu render olur?

Bir Multiply gölgesi, render motoru grubun kendi rengini ve alfasını değil, grubun bileştirilmiş sonucunu blend'e soktuğunda çok koyu çıkar. O sonucun kısmen saydam pikselleri arka planı çoktan içerir; bu yüzden onları arka planla blend'e sokmak, arka planı kendisiyle çarpar. Opaklıkla Normal blending doğrusaldır ve bu hatayı fark edilmeden atlatır; Multiply, Screen, Darken ve diğer tüm doğrusal olmayan modlar atlatmaz

HotPDF rendering hattı, blend modlarını başlangıçta boyanan nesne başına basit ve hızlı bir modelle hallediyordu. Bir nesne boyanmadan önce render motoru etkilenen piksellerin anlık görüntüsünü alır; boyamadan sonra "önce" ile "sonra" bitmap'lerini karşılaştırır, "sonra" rengini opak bir kaynak Cs sayar, B(Cb, Cs) hesaplar ve bunu geçerli opaklıkla bileştirir. Dolgulu bir path, bir glif ya da opak bir görüntü için bu tamamen doğrudur: kaynak gerçekten şeklinin içinde opaktır ve şekil, piksellerin değiştiği yerdir

Bir transparency grubu bu varsayımı bozar. ISO 32000-1 §11.4, grubu kendi rengi ve kendi alfasıyla önce kendi sonucuna bileştirilen ve ancak sonra tek bir nesne olarak arka planla blend'e sokulan bir şey olarak tanımlar. Bir gölgenin opaklığı yüzde 30 olduğunda "sonra" bitmap'i kabaca gölge renginin 0,3'ünü, altındaki sayfanın 0,7'sini taşır. Bunu opak bir kaynak olarak Multiply'a verirseniz formül, arka plan çarpı (arka planı çoktan içeren bir değer) olur: gölge koyulaşır ve arka planın tonunu alır. Hiçbir şey çökmez, hiçbir tanı tetiklenmez ve sayfa düpedüz yanlış görünür; bir render motorunun başarısız olması için en kötü yol budur

HotPDF bir transparency grubuna kendi blend'ini nasıl yaptırır

v2.769.3'ten itibaren HotPDF, Normal dışı bir blend modu altında boyanan bir grubun blend'ini jenerik nesne başına yoldan çıkarıp grup render motorunun kendisine taşır. Grup, Cb(1 − α) + α·B(Cb, Cs) değerini doğrudan kendi renginden, kendi alfasından ve Do operatörü için alınan arka plan anlık görüntüsünden hesaplar; sonra sonucu çoktan blend'lenmiş olarak işaretler, böylece onu saran Do ikinci kez blend'e sokmak yerine yalnızca geçerli opaklıkla bileştirir. Düz nesneler hızlı önce-sonra modelini korur ve Normal blending altındaki gruplar etkilenmez; çünkü doğrusal durum hiç yanlış değildi

Zor kısım alfadır. Bir isolated grup (/I true), tamamen saydam bir arka plandan başlar; bu yüzden render motoru onun için zaten ayrı bir alfa düzlemi izler ve α değerini doğrudan okuyabilir. Bir non-isolated grup, sayfada ne varsa üzerine bileşir ve kendi alfa düzlemi yoktur. HotPDF onu grubu iki kez çizerek kurtarır: bir kez siyah üzerinde, bir kez beyaz üzerinde:

  • Siyah üzerinde her piksel α·Cs olarak biter
  • Beyaz üzerinde aynı piksel α·Cs + (1 − α) olarak biter
  • Çıkarma, α = 1 − (white − black) verir; ardından Cs = black / α

Bu, render motorunun yaptığı her Normal bileşim, soft maskli ve anti-aliasing'li kenarlı görüntüler için GDI AlphaBlend dâhil, arka plan açısından doğrusal olduğu için çalışır. Ama yöntemin bir önkoşulu vardır: grup içeriğinin kendisi normal blend'lenmelidir. Grubun kendi ExtGState kaynakları Normal dışı bir /BM ayarlıyorsa iki geçiş artık temiz bir doğrusal terimle farklılaşmaz; HotPDF grubu bölmez ve önceki davranışa döner. Denetim yalnızca grubun kendi kaynaklarını kapsar, iç içe formları değil. Maliyeti de gerçektir: grup iki kez çizildiği için bu tür sayfalar biraz daha yavaş render olur. Grubun içinde kurulan soft maskler her iki geçiş bitene kadar tutulur; böylece ikinci geçiş, onları yeniden kurmak yerine mask önbelleğine çarpar

// Kanal başına alfa kurtarmanın illüstrasyonu (değerler 0..1).
// Black = siyah arka planda çizilen grup, White = beyaz arka planda.
procedure RecoverGroupPixel(Black, White: Double;
  out Alpha, Source: Double);
begin
  Alpha := 1.0 - (White - Black);
  if Alpha < 0.0 then Alpha := 0.0;
  if Alpha > 1.0 then Alpha := 1.0;
  if Alpha > 0.0 then
    Source := Black / Alpha   // un-premultiply
  else
    Source := 0.0;            // tamamen saydam: renk önemsiz
end;

// Multiply blend, ardından grup bileşimi Cb(1 - a) + a * B(Cb, Cs)
function CompositeMultiply(Backdrop, Source, Alpha: Double): Double;
begin
  Result := Backdrop * (1.0 - Alpha) + Alpha * (Backdrop * Source);
end;

Yukarıdaki kod matematiğin bir illüstrasyonudur, HotPDF API'si değildir; render motoru aynı şeyi THotPDF.RenderLoadedPageToBitmap içinde kanal başına ve piksel başına yapar. Pratikte iki 8 bitlik geçişten kurtarılan alfa sıfıra yaklaştıkça hassasiyet kaybeder; bu yüzden çok soluk kenarlar bir miktar nicemleme gürültüsü taşır ve bölmenin yalnızca alfa belirgin biçimde sıfırın üstündeyken anlamlı olmasının nedeni budur

Blend modu grubun içinde Normal'a sıfırlanır

Blend modu, sabit alfa ve soft mask gibi, transparency grubuna bütün olarak uygulanır, içindeki her nesneye değil; bu yüzden grup içeriği Normal blending'den başlamak zorundadır (ISO 32000-1 §11.6.6). HotPDF daha önce grup girişinde opaklığı ve soft mask'i sıfırlıyor ama blend moduna dokunmuyordu. Bir isolated grubun içindeki sonuç dramatikti: içerik, grubun siyah olan boş başlangıç arka planına kendini çarparak gömerdi ve bütün grup siyah boyanıyordu

Bir soft mask kurulduğunda da aynı sıfırlama geçerlidir. Tek bir ExtGState hem /BM /Multiply hem /SMask ayarlıyorsa mask grubu Normal blending ile çizilmelidir; yoksa beyaz bir mask grubu siyaha döner ve maskin açması gerekeni tam olarak gizler. İki sıfırlama da v2.769.3'ün parçasıdır ve ikisi de basit belgelerde görünmezdir; bu kadar uzun süre yaşamalarının nedeni budur

Bir luminosity soft mask orta gri için hangi değeri almalı?

ISO 32000-1'e göre grubu CIE tabanlı bir blending uzayı kullanan bir luminosity soft mask CIE 1931 Y almalıdır ve 0,5'lik bir sRGB orta grisi için Y yalnızca kabaca 0,21'dir; çünkü Y doğrusal ışıktır. Yaygın PDF görüntüleyicileri ise grup rengini RGB'ye çözümler ve kodlanmış değerleri kabaca 0,30 / 0,59 / 0,11 ile ağırlıklandırır; bu da aynı gri için kabaca 0,5 verir. v2.770.0'den itibaren HotPDF varsayılan olarak görüntüleyici uyumlu ağırlıklamayı kullanır ve şartname okuması için THotPDF.RenderColorimetricLuminosityMasks özelliğini sunar

Fark akademik değildir. Tasarım aracı çıktısındaki bir solma genellikle ICCBased ya da kalibre edilmiş bir gruptaki bir degradadır ve orta tonlar, doğrusal Y ile gamma kodlu griyin en çok ayrıştığı yerdir. CIE Y ile orta grili bir mask, gölgenin yarısı yerine yalnızca beşte birini geçirir; böylece drop shadowlar ve vinyetler, müşterinin dosyayı açtığı diğer her görüntüleyiciden belirgin biçimde daha açık çıkar. Standardın harfiyle haklı ama herkesin gözüne göre yanlış olmak, bir varsayılan için kötü bir takastır; bu yüzden varsayılan görüntüleyicileri izler ve katı mod bir özellik ötedir

var
  Pdf: THotPDF;
  Bmp: TBitmap;
begin
  Pdf := THotPDF.Create(nil);
  try
    if Pdf.LoadFromFile('catalog-page.pdf') > 0 then
    begin
      // Varsayılan (False): luminosity maskler çözümlenen rengi
      // DeviceRGB gibi ağırlıklandırır; yaygın görüntüleyicilerin gösterdiğiyle eşleşir.
      // True: mask grubunun CIE tabanlı bir uzayı varsa CIE Y al.
      Pdf.RenderColorimetricLuminosityMasks := False;
      Bmp := Pdf.RenderLoadedPageToBitmap(0, 150);
      if Bmp <> nil then
      try
        Bmp.SaveToFile('catalog-page-viewer.bmp');
      finally
        Bmp.Free;
      end;
    end;
  finally
    Pdf.Free;
  end;
end;

Özellik yalnızca mask grubunun blending uzayı CIE tabanlı olduğunda önem taşır: CalGray, CalRGB, Lab ya da ICCBased. Grubu DeviceGray, DeviceRGB ya da DeviceCMYK kullanan maskler, her iki ayarda da tam olarak eskisi gibi render olur; çünkü cihaz uzayından griye dönüşüm iki modda da aynıdır

Tuzaklar: /BC, /CS ve render önbelleği

Bir luminosity soft mask, arka planı kadar tutarlıdır: grubun dışında mask alanını dolduran /BC rengi, grubun içindeki boyayla aynı kuralla dönüştürülmelidir. HotPDF her ikisini de v2.770.0'de birlikte değiştirdi. Boyayı ağırlıklı RGB ile ama arka planı CIE Y ile dönüştürmek, grubun bounding box'ının bittiği yerde görünür bir dikiş üretir; arka plan içerikten farklı bir yardımcıdan geçtiğinde kolayca düşülen bir hatadır

Grup özniteliklerinin de bütün bunlar olmadan önce geçerli olması gerekir. HotPDF blending uzayını grubun /CS girişinden okur ve /BC'nin o uzayın bileşeni başına tam olarak bir sayı taşımasını ister: RGB tabanlı uzay için üç, CMYK için dört, gri için bir. Eksik bir /CS ya da yanlış eleman sayılı bir /BC, maski grup çalışmadan düşürür ve boya, tahmin edilmiş bir arka planla masklenmek yerine maskesiz çizilir. Separation, DeviceN ve NChannel meşru blending uzayları değildir; bu yüzden bir mask grubundaki spot renk boya, luminosity hesaplanmadan tint dönüşümüyle alternatif uzaya geçer

Son olarak, ayar pikselleri değiştirir; bu yüzden önbellek anahtarının parçasıdır. RenderColorimetricLuminosityMasks açık ve kapalıyken render edilen bitmapler, hem bellek hem disk render önbelleklerinde ayrı ayrı saklanır ve THotPDF.RenderLoadedPageToBitmapCached çağrıları arasında özelliği çevirmek asla diğer moddan bir bitmap döndürmez. Operasyonel bir not: v2.769.3, kendi soft mask'ini ayarlamamış bir transparency grubu içeren sayfaların render edilemediği yalnızca Win64'te görülen bir gerileme getirdi; v2.770.1'de düzeltildi, bu yüzden 64 bit uygulamalar o sürümü ya da sonrasını kullanmalı

// Yan yana proofing: aynı sayfayı iki modda da render edin.
// Her mod kendi anahtarı altında önbelleklenir; tekrarlanan çağrılar ucuzdur.
Pdf.RenderColorimetricLuminosityMasks := False;
ViewerBmp := Pdf.RenderLoadedPageToBitmapCached(PageIndex, 96);

Pdf.RenderColorimetricLuminosityMasks := True;
StrictBmp := Pdf.RenderLoadedPageToBitmapCached(PageIndex, 96);

// ... ikisini de gösterin, sonra serbest bırakın: önbellekli çağrılar sahibi çağıran olan kopyalar döndürür
ViewerBmp.Free;
StrictBmp.Free;

DPI seçimi, sayfa önbelleği ve render motorunun hâlâ yaklaştırdığı şeyler dâhil daha geniş rendering API'si için HotPDF ile bir PDF sayfasını Delphi TBitmap'e render etme yazısına bakın. Sorununuz ters yöndeyse, onu çizmek yerine baskı ya da arşiv için bir dosyadan saydamlığı kaldırmaksa, PDFlibPas'ta soft maskler ve transparency düzleştirme o tarafı ele alır

FAQ

HotPDF, transparency gruplarının içindeki PDF blend modlarını doğru render ediyor mu?

Evet, v2.769.3'ten itibaren. Multiply ya da başka bir Normal dışı blend moduyla boyanan bir grup kendi rengini ve alfasını arka planla blend'ler ve içeriği, ISO 32000-1 §11.6.6'nın istediği gibi Normal blending'den başlar

HotPDF non-isolated grupları neden iki kez render eder?

Bir non-isolated grubun kendi alfa düzlemi yoktur. HotPDF onu siyah ve beyaz üzerinde çizer ve alfa değerini 1 − (white − black) olarak kurtarır; bu bir miktar hızdan ödün verdirir ama Multiply gölgelerini doğru yapar

RenderColorimetricLuminosityMasks'i True yapmalı mıyım?

Yaygın PDF görüntüleyicilerinin gösterdiğiyle eşleşmesi için False bırakın. True yalnızca CIE tabanlı mask grupları için ISO 32000-1'in CIE Y okumasına, örneğin bir uyumluluk karşılaştırmasında ihtiyacınız olduğunda ayarlayın

Blend modlu transparency grupları, luminosity soft maskler ve onları çizen sayfa render motoru, harici DLL olmadan PDF belgeleri oluşturan, düzenleyen ve render eden yerel bir VCL kütüphanesi olan HotPDF Delphi Component'in parçasıdır