Bir hasar (claims-processing) işleme ekibinin yaprak beslemeli (sheet-fed) bir tarayıcıdan geçen otuz yıllık kağıt dosyaları vardı. Tarayıcı her sayfa için bir klasöre 0001.jpg, 0002.jpg ve benzeri isimlerde bir JPEG tükürdü (spat out). Arşivin aslında ihtiyaç duyduğu şey, bir inceleyicinin (reviewer) yüzlerce küçük resme (thumbnails) tıklamak yerine tek bir belge açabilmesi için sayfaların sırayla (in order) olduğu vaka dosyası (case file) başına tek bir PDF'di. Numaralandırılmış bir tarama yığınını (pile) tek bir sıralı (ordered) PDF'ye dönüştüren bu son adım, buradaki iştir
PDFium Bileşeni (Component) bunu doğrudan (directly) halleder. Oluşturma (rendering) ve metin çıkarmanın (extraction) ötesinde, bileşen sıfırdan bir PDF oluşturabilir: boş bir belge oluşturun, istediğiniz boyutta (sized however you like) boş bir sayfa ekleyin, kullanıcı uzayı (user-space) koordinatlarında o sayfaya bir görüntü bırakın (drop), ardından kaydedin. Tüm boru hattı (pipeline) TPdf bileşeni üzerinde yaşar, bu nedenle bir toplu (batch) dönüştürücü dosya adları üzerinde bir döngü artı (plus) bir avuç çağrıdır (calls)
Dönüşümün (conversion) şekli
Her tarama (scan) için üç şeyin gerçekleşmesi gerekir. Sayfa boyutuna (size) karar (decide) verirsiniz, bir kenar boşluğu (margin) bırakarak görüntüyü (image) sayfanın içine (inside) yerleştirirsiniz ve bir sonraki sayfaya (page) ilerlersiniz (advance). PDFium Bileşeni (Component) her biri (each) için size bir yöntem (method) sunar (gives): AddPage verilen (given) bir boyutta boş (blank) bir sayfa oluşturur (creates), AddImage (veya zaten (already) bir TPicture tutuyorsanız (hold) AddPicture) bit eşlemi (bitmap) geçerli (current) sayfaya (page) çizer (draws) ve PageNumber bileşene daha (subsequent) sonraki çizim çağrılarının (calls) hangi (which) sayfayı hedeflediğini (target) söyler
İnsanları çelmeleyen (trips up) tek (one) detay koordinat (coordinate) sistemidir (system). PDF kullanıcı (user) alanı (space), Delphi geliştiricilerinin refleks olarak uzandığı (reach for) ekran (screen) koordinatlarının aksine (opposite), orijini (origin) sayfanın sol (lower-left) alt (lower-left) köşesine (corner) koyar ve Y yukarı doğru (upward) artar (increasing). AddImage'a geçirdiğiniz (pass) X, Y görüntü dikdörtgeninin (rectangle) sol (lower-left) alt köşesidir ve Width, Height kaynak dosyanın (file) piksel boyutu değil, nokta (points) cinsinden (in) yerleşim (placement) boyutudur. Bunu geriye (backwards) alın ve taramalarınız sayfanın (page) dışına iner (land) veya (or) onları beklediğiniz yere (where) göre ters (upside down) döner
Belgeyi (document) ve (and) tarama (scan) başına bir (a) sayfa oluşturma
Boş (empty) bir belge (document) ile (with) başlayın (Start). CreateDocument taze (fresh) bir PDF ayırır (allocates) ve (and) bileşeni (component) aktif (active) bırakır (leaves), bu nedenle ayrı (separate) bir (no) açık (open) adım (step) yoktur (no). Oradan taranmış dosyaların listesinde yürürsünüz (walk) ve her biri için (for each one) bir sayfa ekler (add), onu geçerli (current) yapar (make) ve görüntüyü yerleştirirsiniz (place). Buradaki sayfa (Page) boyutları (dimensions), arşivlenmiş (archived) yazışmalar (correspondence) için standart sayfa (sheet) boyutu (size) olan nokta (points) cinsinden (in) A4'tür (595 × 842 dikey (portrait))
procedure TArchiveForm.ScansToPdf(const Files: TStrings; const OutputPath: string);
const
PageW = 595.0; // A4 width in points
PageH = 842.0; // A4 height in points
Margin = 36.0; // half-inch border around each scan
var
I: Integer;
Pdf: TPdf;
begin
Pdf := TPdf.Create(nil);
try
Pdf.CreateDocument; // new, empty, already active
for I := 0 to Files.Count - 1 do
begin
Pdf.AddPage(I + 1, PageW, PageH); // 1-based page index
Pdf.PageNumber := I + 1; // make the new page current
PlaceScan(Pdf, Files[I], PageW, PageH, Margin);
end;
Pdf.SaveAs(OutputPath);
finally
Pdf.Free;
end;
end;
Her yineleme (iteration) bir sayfa (page) oluşturur (creates) ve (and) hemen (immediately) ona PageNumber'ı ayarlar (sets). Bu (That) ikinci (second) satır (line) önemlidir (matters): AddPage sayfayı ekler (inserts) ancak (but) çizim (draw) yöntemleri (methods) hangi (whichever) sayfa (page) geçerliyse (current) onda (on) hareket eder (act), bu nedenle (so) PageNumber'ı ayarlamak (setting), AddImage'ı yeni (just) yaptığınız sayfaya yönelten (aims) şeydir (what). Onu atlayın (Skip it) ve resimleriniz daha (before) önce (before) yüklü (loaded) olan hangi sayfa (page) tesadüfen (happened to) geldiyse (happened to) onun üzerine istiflenir (stack)
Bu döngüde bir varsayım (assumption) saklanıyor (hides): Files sırası (order). Bir tarayıcı (scanner) sayfaları (pages) 0001.jpg'den 0100.jpg'ye kadar (through) isimlendirir (names), ancak (but) bir dizin (directory) numaralandırması (enumeration) bunları her zaman sıralanmış (sorted) olarak (always) döndürmez (does not) ve (and) page10.jpg'nin (page10.jpg) yanındaki (next to) page9.jpg'ye bastığınız an (moment) düz (plain) bir dize (string) sıralaması (sort) sayfa 10'u sayfa 9'un önüne koyar (puts). Döngüden (loop) önce listeyi (list) açıkça (explicitly) sıralayın (Sort) ve (and) tarama (scan) zamanında (time) sözlüksel (lexical) sıranın (order) sayfa (page) sırasıyla eşleşmesi (matches) için sıfırla desteklenmiş (zero-padded) isimleri (names) tercih (prefer) edin. Sayfa (Page) dizisi (sequence), bir inceleyicinin (reviewer) anında (immediately) fark ettiği (notices) tek (one) şeydir (thing) ve (and) önlenmesi (prevent) en (cheapest) ucuz hatadır (mistake)
Bir taramayı (scan) yerleştirmek ve en (aspect) boy oranını korumak (keeping)
Bir tarama (scan) nadiren sayfa (page) ile aynı (same) şekildedir (shape). Yaprağı (sheet) doldurmak (fill) için gererseniz (stretch) metni (text) bozarsınız (distort); tam piksel (pixel) boyutunda (size) yerleştirirseniz (place) taşar (overflows). Çözüm (fix), iki orandan (ratios) daha (smaller) küçük olanına, genişliğe (width-fit) sığdırma (width-fit) veya yüksekliğe (height-fit) sığdırma (height-fit), göre ölçeklendirmek (scale) ve (and) geriye kalanı (left over) ortalamaktır (center). Orijin (origin) sol altta (lower-left) oturduğundan (sits), ortalamak (centering), kalan boşluğu (space) eşit olarak (evenly) bölmek (splitting) ve hem X hem de Y'ye eklemek (adding) anlamına gelir (means)
procedure TArchiveForm.PlaceScan(Pdf: TPdf; const FileName: string;
PageW, PageH, Margin: Double);
var
Pic: TPicture;
AvailW, AvailH, Scale, DrawW, DrawH, X, Y: Double;
begin
Pic := TPicture.Create;
try
Pic.LoadFromFile(FileName); // BMP, JPG, PNG, etc. via the VCL graphics units
AvailW := PageW - 2 * Margin;
AvailH := PageH - 2 * Margin;
// Fit inside the margins without distorting the scan.
Scale := Min(AvailW / Pic.Width, AvailH / Pic.Height);
DrawW := Pic.Width * Scale;
DrawH := Pic.Height * Scale;
// Center: leftover space split evenly. Y measured from the page bottom.
X := (PageW - DrawW) / 2;
Y := (PageH - DrawH) / 2;
Pdf.AddImage(FileName, X, Y, DrawW, DrawH);
finally
Pic.Free;
end;
end;
Bu, piksel (pixel) boyutlarını (dimensions) okumak için dosyayı bir kez yükler, tek bir (single) tek tip (uniform) ölçek hesaplar ve yerleşim (placement) dikdörtgenini (rectangle) AddImage'a iletir (passes). AddImage doğrudan (directly) bir dosya yolu (path) kabul eder (accepts) ve onu AddPicture ile aynı görüntü ardışık düzeninden (pipeline) yönlendirir (routes), böylece (so) VCL grafik (graphics) birimlerinin (units) tanıdığı herhangi bir (any) format (format), özel durum (special-casing) gerektirmeden çalışır (works). Resmi önizleme bölmesinden (preview pane) bir TPicture'da zaten deşifre ettiyseniz (decoded), aynı (same) dikdörtgen (rectangle) ile AddPicture(Pic, X, Y, DrawW, DrawH)'yi çağırın ve ikinci dosya okumayı atlayın (skip)
JPEG taramaları (scans) için deşifrelemeyi (decode) atlama (Skipping)
Tarayıcılar (Scanners) neredeyse her zaman JPEG çıkarır (emit). Bir JPEG'i bir TPicture'a yüklemek onu bir bitmap'e (bitmap) çözer (decodes) ve daha sonra PDFium kaydederken (save) onu yeniden (re-encodes) kodlar, ihtiyacınız olmayan (do not need) iki kayıplı (lossy) gidiş-dönüş (round trips). AddJpegImage orijinal sıkıştırılmış (compressed) baytları (bytes) bir (a) akıştan (stream) doğrudan (straight) sayfaya (page) gömer (embeds), ki bu (which) yüksek (high-volume) hacimli (high-volume) bir (a) toplu iş (batch) için (for) hem (both) daha hızlı (faster) hem de görsel olarak (visually) daha (cleaner) temizdir
var
Stream: TFileStream;
begin
// ... after AddPage + PageNumber for the current page ...
Stream := TFileStream.Create(FileName, fmOpenRead);
try
// Embeds the JPEG bytes as-is; no decode/re-encode cycle.
Pdf.AddJpegImage(Stream, X, Y, DrawW, DrawH);
finally
Stream.Free;
end;
end;
Piksel boyutlarına (dimensions) ölçeklemek (scale) için (since) hala X, Y, DrawW ve (and) DrawH'yi aynı (same) şekilde (way) hesaplıyorsunuz (compute). Onları (those) dosyadan (file) veya hızlı (quick) bir (a) başlık (header) ayrıştırmasından (parse) okuyun (Read), ardından (then) ham (raw) akışı (stream) AddJpegImage'a elden (hand) verin. PNG veya (or) TIFF taramaları (scans) için (For) AddImage yolu (path) doğru (right) olandır (one); JPEG kısayolunu (shortcut) gerçekten (actually) geçerli olduğu format (format) için ayırın (reserve)
Her (each) sayfayı (page) etiketleme (Labeling)
Her (each) sayfa (page) kaynak (source) dosya adını taşıdığında (carries) arşivlenmiş (Archived) taramaların denetlenmesi (audit) daha (easier) kolaydır. AddText kullanıcı alanı (user-space) koordinatında (coordinate) bir (a) dize (string) çizer (draws), böylece (so) bir altyazı (caption) görüntünün hemen (just) altında (under) oturur (sits). Ters çevrilmiş (inverted) Y eksenini unutmayın (Remember): taramanın (scan) altına (below) bir (a) etiket (label) koymak (put) için (to), ona (it) eklemek (add to) yerine (rather than) görüntünün alt (bottom) kenarından çıkarırsınız (subtract)
// Caption below the scan: Y decreases toward the page bottom.
Pdf.AddText('File: ' + ExtractFileName(FileName), 'Helvetica', 9,
X, Y - 14, clGray);
Kaydetme ile ilgili (about) son (last) bir (One) nokta (point). SaveAs, Boole (Boolean) döndüren (returns) bir işlevdir, bu nedenle üretim (production) kodunda yazmanın başarılı (succeeded) olduğunu varsaymak (assuming) yerine (rather than) sonucunu (result) kontrol edin; (check) aksi takdirde tam (full) bir disk veya (or) kilitli (locked) bir çıktı (output) yolu (path) sessizce (quietly) başarısız olur. Döngü bittiğinde (finishes) ve (and) dosya yazıldığında, tam olarak (exactly) arşivin ihtiyacı olan (needed) şeye sahipsiniz: durum (case) dosyası (file) başına (per) sıralanmış bir (one) PDF, sığacak (fit) şekilde (to) ölçeklenmiş sayfalar, herhangi bir (any) görüntüleyicide (viewer) okumaya hazır (ready)
Aynı yapı taşları (building blocks) ilgili işleri kapsar. Sayfa (per-page) başına (per) boyutlandırma (sizing) kuralını değiştirin ve yaprak başına bir görüntü (image) içeren (with) bir fotoğraf kitabı elde edersiniz; döngüyü tutun (keep) ancak çok (multi-page) sayfalı (multi-page) bir TIFF kaynağından (source) okuyun (read) ve (and) bir faks arşivi (fax-archive) dönüştürücüsüne sahip olun. Programlı (programmatically) olarak PDF'ler (PDFs) oluşturmanın (building) daha (wider) geniş (wider) bir resmini istiyorsanız, PDFium Bileşeni (Component) ile sıfırdan PDF belgeleri oluşturma konusuna (see) bakın (see); sonucu daha (later) sonra (later) tekrar ekrana oluşturmak (render) için (to), PDFium Bileşeni ile PDF sayfalarını JPEG resimlerine dönüştürme konusuna bakın
loslab.com'dan PDFium Bileşeni, bu (this) seri (series) boyunca (throughout) kullanılan belge-oluşturma, oluşturma ve metin API'lerini (APIs) bir araya getirir (bundles)