Bir PDF sayfasını (page) JPEG'e oluşturmak (Rendering), insanların birlikte yürütme (run together) ve ardından (then) ayrı ayrı (separately) ayıklama (debug) eğiliminde (tend) olduğu iki işlemdir (operations). Önce (First) sayfayı (page) seçtiğiniz (choose) bir (a) çözünürlükte (resolution) piksel (pixel) bitmap (bitmap) halinde (into) rasterleştirirsiniz (rasterize). Sonra o bitmap'i bir JPEG kodlayıcıya (encoder) elden verirsiniz (hand) ve bir kalite (quality) seçersiniz (pick). PDFium Bileşeni, ilk yarıya RenderPage aracılığıyla (through) sahiptir (owns); ikinci (second) yarı (half) düz (plain) VCL, Vcl.Imaging.jpeg'den TJPEGImage'dir. Aralarındaki dikiş (seam), ilginç kararların yaşadığı (live) yerdir, çünkü (because) oluşturma (render) tarafında (side) seçtiğiniz çözünürlük (resolution) ve (and) kodlama (encode) tarafında seçtiğiniz kalite, birbirine ve (and) dosya (file) boyutuna (size) karşı yanlış yapması kolay yollarla birbirini (each other) takas eder (trade off)
Herhangi bir (any) koddan önce (before) içselleştirilmesi (internalize) gereken şey: bir (a) PDF sayfasının pikseli (pixels) yoktur (no). Bir noktanın inçin 1/72'si olduğu noktalarda (points) açıklanır (described) ve (and) sayfa, bu (those) noktalarda (points) ölçülen vektör (vector) bir (a) çizimdir (drawing). PDFium'dan (PDFium) oluşturmasını istediğinizde (ask), bu (that) çizimi (drawing) kaç (how many) piksel (pixels) üzerine (onto) yansıtacağınızı seçiyorsunuz (choosing), ve bu (that) seçim (choice) DPI'dır. Aritmetiği (arithmetic) yanlış (wrong) yaparsanız, bir (a) baskı (print) yöneticisi (master) istediğinizde (wanted) bulanık (blurry) bir küçük resim oluşturursunuz (render) veya 120 (120-pixel) piksellik bir önizleme (preview) olması amaçlanan (destined) bir (a) şey için (for) 200 (200-megapixel) megapiksel bir bitmap atarsınız (allocate)
DPI'den piksel (pixel) boyutlarına (dimensions)
RenderPage, DPI değil, tamsayı (integer) piksel Width ve Height istiyor. Dolayısıyla ilk (first) iş (job) dönüştürmedir (converting). Bir sayfa, boyutunu PageWidth ve (and) PageHeight (her ikisi (both) de Double) aracılığıyla noktalar (points) cinsinden bildirir ve (and) dönüşüm (conversion), her (every) rasterizerin (rasterizer) kullandığıyla aynıdır: piksel eşittir (equal) nokta (points) çarpı (times) hedef (target) DPI bölü (divided by) 72. ABD (US) Letter sayfası 612'ye 792 noktadır (points). 150 DPI'da 1275'e 1650 piksel (pixels) olur (becomes); 72 DPI'da 612'ye 792'de (stays) kalır, nokta (point) başına bir (one) piksel, ki bu (which) insanların unuttuğu (forget) durum, sadece (just) kimliktir (identity)
// Pdf.PageNumber must already point at the page you want.
PixelW := Round(Pdf.PageWidth * Dpi / 72);
PixelH := Round(Pdf.PageHeight * Dpi / 72);
Bitmap := Pdf.RenderPage(0, 0, PixelW, PixelH, ro0, [], clWhite);
// ... use Bitmap ...
Bitmap.Free; // the function-form RenderPage hands you ownership
Bu (those) dört satırdaki (lines) iki (Two) ayrıntı (details) kodun (code) doğru (correct) olup (whether) olmadığına (whether) karar verir (decide). Birincisi (first), RenderPage işlev (function) formunun (form) size ait (own) olan bir TBitmap döndürmesidir (returns). PDFium (PDFium) onu tahsis (allocated) etti ve (and) uzaklaştı (walked away); her (every) yinelemede (iteration) onu serbest bırakmazsanız (Free), birkaç yüz sayfa üzerindeki bir toplu (batch) iş, birkaç yüz bitmap'i (bitmaps) sızdırır (leaks) ve bir şey düşene (falls over) kadar süreç (process) şişer (bloats). İkincisi, buradaki clWhite olan Color argümanıdır (argument). PDF sayfaları (pages) genellikle (usually) opak (opaque) beyaz (white) bir substrat (substrate) varsayılarak (assuming) çizilir (drawn) ve (and) yanlış (wrong) arka (background) plan rengi (color) üzerine (onto) saydamlık (transparency) ile (with) işlenmiş bir sayfa çamurlu (muddy) kenarlar (edges) veya sokak (stray) karanlık (dark) haleleri (halos) üretir. Beyaz, neredeyse (almost) her belge için (for) doğru (right) varsayılandır (default); parametre, olmadığı (not) nadir (rare) durum (case) için (for) mevcuttur (exists)
0, 0, ölçeklenmiş (scaled) koordinat (coordinate) alanındaki, sayfaya (page) doğru Left ve Top uzaklıklarıdır (offsets) ve kırpmıyorsanız (cropping) bunları sıfırda (zero) bırakırsınız (leave). ro0 dönüş (rotation): sıfırda bırakın ve PDFium (PDFium), sayfanın (page) /Rotate girişinde zaten bildirdiği dönüşü (rotation) onurlandırır (honors), böylece manzara (landscape) olarak oluşturulan (authored) bir sayfa, siz hiçbir (anything) şey (anything) yapmadan (without) manzara olarak çıkar
Bit eşlemi JPEG olarak kodlama
Bitmap (bitmap) bir kez (Once) var olduğunda, JPEG kolay (easy) kısımdır (part) ve (and) saf (pure) Delphi'dir. TJPEGImage.Assign bit eşlemi içine (in) kopyalar (copies), CompressionQuality 1'den (1) 100'e (100) kadar bir ölçekte kaliteyi ayarlar ve SaveToFile dosyayı (file) yazar (writes). Tek sipariş kuralı (rule), kaliteyi (quality) kaydetmeden önce ayarlamanız gerektiğidir, çünkü (because) SaveToFile'in tetiklediği kodlamayı yönetir (governs)
uses
Vcl.Graphics, Vcl.Imaging.jpeg, PDFium;
procedure SavePageAsJpeg(Pdf: TPdf; PageNumber, Dpi, Quality: Integer;
const FileName: string);
var
Bitmap: TBitmap;
Jpeg: TJPEGImage;
begin
Pdf.PageNumber := PageNumber;
Bitmap := Pdf.RenderPage(0, 0,
Round(Pdf.PageWidth * Dpi / 72),
Round(Pdf.PageHeight * Dpi / 72),
ro0, [], clWhite);
try
Jpeg := TJPEGImage.Create;
try
Jpeg.Assign(Bitmap);
Jpeg.CompressionQuality := Quality; // 1..100
Jpeg.SaveToFile(FileName);
finally
Jpeg.Free;
end;
finally
Bitmap.Free;
end;
end;
Bu içi içe (nested) try/finally tek sayfalık bir yardımcı (helper) için telaşlı (fussy) görünüyor ve (and) bir toplu (batch) iş için (for) tam (exactly) olarak (exactly) doğru (right). İç blok kodlayıcıyı (encoder) serbest bırakır, dış (outer) blok bit eşlemi (bitmap) serbest (frees) bırakır ve bir istisna üzerinde (on) ateşlenen (firing) her (either) biri (one) hala sahip (owns) olduğu şeyi (what) serbest bırakır (releases). Bunları bire (one) daraltın (Collapse) ve kodlama (encoding) sırasındaki bir istisna bit eşlemi (bitmap) karaya (strand) oturtabilir. Uzun bir çalışma boyunca, bu (that), biten (finishes) bir (a) dönüştürücü ile bozuk bir dosya (file) ve yetersiz (out-of-memory) bellek iletişim kutusuyla (dialog) sayfa 300'de ölen bir (one) dönüştürücü arasındaki (between) farktır
DPI ve kaliteyi birlikte (together) seçmek (Choosing)
İki düğme (knobs) çıktının (output's) amacından bağımsız (independent) değildir ve (and) yaygın (common) hata, dikkatten dolayı her ikisini de (both) açmaktır. 300 DPI'da işlenen ve (and) 95 kalitesinde (quality) kaydedilen (saved) bir web küçük resmi (thumbnail), 120 piksel (120-pixel) bir (a) görüntü (image) gibi davranan birkaç yüz (hundred) kilobayttır; tarayıcı (browser) onun (it) hemen hemen tamamını küçültme (downscale) işlemi sırasında çöpe atar (throws away). Çözünürlüğü, çıktının gerçekten ihtiyacı olan piksellerle (pixels) eşleştirin, ardından (then) görünür eserler olmadan JPEG'in kayıplı sıkıştırmasından (compression) kurtulan bir (a) kalite (quality) seçin (pick)
| Çıktı (Output) | DPI | JPEG kalitesi |
|---|---|---|
| Liste (List) küçük resmi (thumbnail) | 72 | 60-70 |
| Ekran (On-screen) önizlemesi (preview) | 96-150 | 80-85 |
| Yüksek detaylı (High-detail) görüntüleme (viewing) | 200-300 | 85-95 |
| Yazdırma (Print) yöneticisi (master) | 300-600 | 90-100 |
JPEG kalitesi (quality) tek başına (own) bir dikkat kelimesine (word) değer (worth). Bu doğrusal (linear) bir kadran (dial) değildir (not). 70'ten 85'e atlama, mütevazı (modest) bir dosya büyümesi için gerçek bir görsel iyileştirme satın alır; 95'ten 100'e atlama, hemen hemen hiç kimsenin göremediği bir fark (difference) için (for) dosyayı yaklaşık (roughly) iki katına (doubles) çıkarır, çünkü 100 kalite (quality) hala kayıpsız (lossless) değildir, sadece fazla şeyi atmayı bırakır (stops). Metin ağırlıklı sayfalar için, JPEG'in blok (block-based) tabanlı sıkıştırması, gliflerin (glyphs) keskin (sharp) kenarlarını zayıf (faint) çalmaya bulaştırır, bu nedenle yaklaşık 80'in altındaki (below) kalite (quality), canlı (crisp) çıkış (output) olması (should) gereken (what) şeyde tarayıcı gibi (scanned-looking) görünen (looking) metin (text) yapar (makes). Sayfalar (pages) çoğunlukla (mostly) metin (text) ise ve formatları değiştirebiliyorsanız, PNG bu (that) metni (text) zil sesi olmadan işler; JPEG, fotoğrafik (photographic) ve sıkıştırmasının gerçekten daha (smaller) küçük olduğu karışık içerikte (content) yerini (place) kazanır (earns)
Daha hızlı, daha küçük küçük resimler
Hedef (target) sadık (faithful) bir üreme yerine (rather than) bir küçük resim (thumbnail) olduğunda, oluşturucuya (renderer) daha (less) az iş yapmasını söyleyebilirsiniz. Options parametresi bir dizi TRenderOption bayrağı (flags) alır ve bunlardan birkaçı (few), tam (exactly) olarak (exactly) küçük bir önizlemenin istediği (wants) şekilde, hız (speed) için sadakati takas eder (trade). reGrayscale rengi bırakır, bu hem (which both) daha (faster) hızlı (faster) işlenir (renders) hem de (and) kodlanacak (encode) daha (smaller) küçük (smaller) bir bitmap üretir (produces). reNoSmoothImage ve reNoSmoothPath, küçük resim (thumbnail) ölçeğinde (scale) zaten (anyway) görünmeyen (invisible) kenar yumuşatmayı (anti-aliasing) atlar (skip)
function RenderThumbnail(Pdf: TPdf; PageNumber, MaxW, MaxH: Integer): TBitmap;
var
Scale: Double;
begin
Pdf.PageNumber := PageNumber;
// Fit the page inside MaxW x MaxH while preserving aspect ratio.
Scale := Min(MaxW / Pdf.PageWidth, MaxH / Pdf.PageHeight);
Result := Pdf.RenderPage(0, 0,
Round(Pdf.PageWidth * Scale),
Round(Pdf.PageHeight * Scale),
ro0, [reGrayscale, reNoSmoothImage], clWhite);
end;
Küçük (thumbnail) resim (thumbnail) durumu (case) ayrıca (also) boyutlandırmayı düşünmenin (think) daha temiz (cleaner) yolunu gösterir (shows). DPI üzerinden (through) gitmek yerine (Instead of), sayfayı (page) sınırlayıcı (bounding) bir kutunun (box) içine sığdıran (fits) ve (and) en boy (aspect) oranını koruyan (preserves) tek bir (a) ölçek (scale) faktörü (factor) hesaplayın (compute), ki (which) bu, iki (two) oranın Min'inin yaptığı (does) şeydir (what). Hem dikey (portrait) bir sayfa hem de yatay (landscape) bir sayfa bozulma olmadan aynı kutunun (box) içine (inside) girer (end up) ve hiçbir (never) zaman (never) "200'e 280 sığdırmaya" ("fit in 200 by 280") hangi (what) DPI'nin karşılık (corresponds) geldiği (to) konusunda (about) akıl yürütmek zorunda (reason) kalmazsınız. reGrayscale ile bir (One) uyarı (caveat): raster görüntü (image) içeriğini (content) griye dönüştürür (converts), ancak (but) vektör (vector) dolguları (fills) ve metin, motorda (engine) renk değerlerini tutar (keep), böylece (so) çoğunlukla (mostly) vektör (vector) sanatı (art) olan bir sayfa, bayrağın (flag's) adının (name) önerdiğinden daha az monokrom (monochrome) olarak geri dönebilir. Gerçek (true) bir tam (full-grayscale) gri tonlamalı (full-grayscale) sonuç (result) için, işlenen (rendered) bit eşlemi (bitmap) GrayscalePdfBitmap ile dönüştürmek, güvenilir yoldur
Tüm bir (a) belgeyi toplu (Batching) işleme (Batching)
Onu tam (full) bir belge (document) için (for) bir araya (together) getirmek, her (at a time) seferinde (at a time) bir sayfa (page) hareket (moved) eden PageNumber ile (with) PageCount üzerinden (over) bir (a) döngüdür (loop). Sayfalar (Pages) 1 tabanlıdır (1-based): birinci (one) sayfa PageNumber := 1'dir ve döngü PageCount - 1'e değil PageCount'a (dahil) kadar (to) çalışır (runs). Grubun (batch) saygı göstermesi gereken diğer (other) şey (thing), sessiz (silent-load) yükleme (silent-load) sözleşmesidir (contract). Active := True ayarı (Setting), hasarlı (damaged) bir (a) dosya (file) veya yanlış (wrong) bir parola (password) üzerinde asla kalkmaz (raises); (it) sadece Active değerini False olarak bırakır (leaves). Tek (single) bir sayfayı (page) işlemeden (render) önce (before) onu (it) kontrol (Check) edin, aksi takdirde ilk (first) RenderPage hiç (never) açılmamış bir (a) belgeye (document) karşı (against) çalışır
procedure ExportAllPages(const PdfPath, OutDir: string; Dpi, Quality: Integer);
var
Pdf: TPdf;
I, Digits: Integer;
begin
Pdf := TPdf.Create(nil);
try
Pdf.FileName := PdfPath;
Pdf.Active := True;
if not Pdf.Active then
raise Exception.Create('Could not open ' + PdfPath);
Digits := Length(IntToStr(Pdf.PageCount)); // zero-pad so files sort right
for I := 1 to Pdf.PageCount do
SavePageAsJpeg(Pdf, I, Dpi, Quality,
Format('%s\page_%.*d.jpg', [OutDir, Digits, I]));
finally
Pdf.Active := False;
Pdf.Free;
end;
end;
Digits aracılığıyla (through) sıfır doldurma (zero-padding), daha sonra bir (an) öğleden sonra kurtaran küçük (small) bir şeydir (thing). Dosyaları page_1.jpg üzerinden (through) page_10.jpg olarak (as) adlandırın (Name) ve (and) bunları dize olarak (as) sıralayan (sorts) herhangi (any) bir araç (tool), page_10'u (page_10) hemen page_1'in arkasına (after) koyarak (puts) sırayı (order) karıştırır (scrambling). En (highest) yüksek (highest) sayfa (page) numarasının (number) genişliğine (width) göre doldurma, böylece (so) 300 (300-page) sayfalık (300-page) bir belge (document) page_001.jpg verir, sözcük (lexical) sırasını (order) ve (and) sayfa sırasını (order) akış (downstream) aşağı (downstream) her yerde (everywhere) aynı tutar (keeps)
Dönüştürmenin fark (noticeable) edilebilir (noticeable) zaman aldığı (takes) yeterince büyük (large) belgeler (documents) için (For), onu kullanıcı (UI) arayüzü (UI) iş parçacığından (thread) çalıştırın veya sayfalar (pages) arasında (between) pompala (pump) mesajları gönderin, böylece (so) uygulama duyarlı (responsive) kalır (stays) ve kullanıcıya (user) durması için (to) bir yol verin. Çok (very) büyük sayfalar oluşturuyorsanız (rendering) ve (and) yalnızca (only) sayfalar (pages) arasında (between) yerine (rather than) sayfa ortasında ısıran bir iptal (cancellation) istiyorsanız (want), PDFium Bileşeni iptal simgesi (token) olan ilerici (progressive) bir oluşturma (render) yoluna (path) sahiptir; bu (that), çoğu (most) toplu (batch) dışa (exports) aktarımın (exports) ihtiyaç (need) duyduğundan (than) daha ağır (heavier) bir mekanizmadır (mechanism), ancak (but) 600 DPI'da (at) tek (single) bir sayfa, engellenecek kadar yavaş olduğunda oradadır
Bilmeye değer son (last) bir (One) eşleştirme (pairing). Bir (a) sayfayı (page) rasterleştirmek, metin (text) katmanını atar (discards): JPEG piksellerdir (pixels) ve içindeki (in) kelimeler (words) artık seçilemez (selectable) veya (or) aranamaz (searchable) değildir (no). Hem bir görüntüye (image) hem de (and) alttaki (underlying) metne (text) ihtiyacınız (need) olduğunda (When), görüntü için işleyin ve metni ayrı (separately) olarak (separately) çekin (pull), ki bu (which) tamamlayıcı parça (companion piece) PDFium Bileşeni ile PDF belgelerinden metin çıkarma kapsar. Burada gösterilen (shown) RenderPage aşırı yüklemeleri (overloads) ve (and) işleme (render) seçenekleri (options), Delphi ve (and) C++Builder için (for) PDFium Bileşeni (Component)'nin bir parçasıdır