powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Кто-нибудь делал паскалевскую обертку над muPDF (libmuPDF.dll)?
20 сообщений из 20, страница 1 из 1
Кто-нибудь делал паскалевскую обертку над muPDF (libmuPDF.dll)?
    #38934452
чччД
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я о той, что в составе Суматры прилагается.
Что-то не рассчитал свои силы. Уже второй день пилю, а края даже не видно...
...
Рейтинг: 0 / 0
Кто-нибудь делал паскалевскую обертку над muPDF (libmuPDF.dll)?
    #38934471
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
чччД,

Когда-то давно здесь, что-то пробегало
...
Рейтинг: 0 / 0
Кто-нибудь делал паскалевскую обертку над muPDF (libmuPDF.dll)?
    #38934479
Фотография defecator
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
Если ты хочешь что-то вытаскивать из PDF файла, то не получится - эта библиотека всего лишь растеризатор PDF.
Годится только для отображения картинок.

В составе Chrome есть библиотека pdf.dll - в ней всё честно, и хидеры, и примеры использования можно найти по слову "Foxit PDF SDK DLL"
...
Рейтинг: 0 / 0
Кто-нибудь делал паскалевскую обертку над muPDF (libmuPDF.dll)?
    #38934497
чччД
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
defecator, мне, в общем, и нужно отображать.
Да еще чтобы поиск по тексту был.
И экспорт в текст. И работа с гиперссылка.
Все это суматра делает, как и тестовый пример из muPDF.
Впрочем, возможно, что поиск и экспорт делаются другими средствами. Исходники тестового примера вроде довольно простые, но подробно я их пока не изучал.
...
Рейтинг: 0 / 0
Кто-нибудь делал паскалевскую обертку над muPDF (libmuPDF.dll)?
    #38934507
Фотография defecator
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
Вот есть перевод libmuPDF под Lazarus:
https://github.com/blestan/lazmupdf
...
Рейтинг: 0 / 0
Кто-нибудь делал паскалевскую обертку над muPDF (libmuPDF.dll)?
    #38934525
чччД
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
defecatorВот есть перевод libmuPDF под Lazarus:
https://github.com/blestan/lazmupdf
Спасибо.

...Ух ты, дешево и сердито. Автор не заморачивался импортом структур, если те использовались в нужных методах в виде ссылки и создавались в недрах библиотеки.
...
Рейтинг: 0 / 0
Кто-нибудь делал паскалевскую обертку над muPDF (libmuPDF.dll)?
    #38936541
чччД
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Небольшой отчет.

defecatorВот есть перевод libmuPDF под Lazarus:
https://github.com/blestan/lazmupdf

Выяснилось, что lazmudpf может работать исключительно с той версией libmuPDF, которая была в момент разработки.
Приложение - пример из lazmudpf использует виджеты библиотеки lazpaint, которую можно загрузить отсюда: http://switch.dl.sourceforge.net/project/lazpaint/src/lazpaint6.4.1_src.zip

lazmudpf с современными версиями libmuPDF не работает.

Вообще, построение libmuPDF.dll для muPDF не предусмотрено, разработчик SumatraPDF готовит её как бесплатное приложение к SumatraPDF.
Текущая версия SumatraPDF - 3.0. И библиотека libmuPDF.dll - тоже 3.0.

Её можно построить самому, загрузив исходники https://kjkpub.s3.amazonaws.com/sumatrapdf/rel/SumatraPDF-3.0-src.7z
Использовать MS VS 2013 комьюнити эдишн.

Экспортируемые из библиотеки методы перечислены в файле libmupdf.def.

Принцип работы с библиотекой довольно прост. Сначала создается т.н. "контекст" библиотеки.
Потом открывается pdf документ.
Одним из свойств документа является количество страниц.
Далее из документа извлекаются нужные страницы.
Страницу можно превратить (например) в png картинку или получить битовую карту изображения.

В последнем случае следует учесть, что просто "бросить" карту на устройство отображения (на "канвас"), то картинка получается отраженной вертикально.
То есть, нужно немножко поработать.
В примере из комплекта лазаруса для вертикального "отражения" используется команда.

Код: pascal
1.
     PaintBox1.Bitmap.VerticalFlip;



Библиотека muPDF поставляется с исходным кодом pdf - браузера, который "почти как суматра".
Выполняется поиск, переход по гиперссылкам, масштабирование...

Но все сии действия реализуются не библиотекой, а ручками. Библиотека помогает. Например, по указанным координатам указателя мыши определить, что за объект там находится: текст, картинка, гиперссылка, встроенный виджет и т.п. А реакцию ты должен писать самостоятельно. то есть, перспективного гемора - маманегорюй.

Имхо, дешевле купить готовый компонент, если есть подходящий.
...
Рейтинг: 0 / 0
Кто-нибудь делал паскалевскую обертку над muPDF (libmuPDF.dll)?
    #38936547
Фотография defecator
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
чччД, что мешает заюзать 17506736
...
Рейтинг: 0 / 0
Кто-нибудь делал паскалевскую обертку над muPDF (libmuPDF.dll)?
    #38936569
Фотография Кроик Семён
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
defecatorВ составе Chrome есть библиотека pdf.dll - в ней всё честно, и хидеры, и примеры использования можно найти по слову "Foxit PDF SDK DLL"

Эта библиотека даже не позволяет высоту страницы получить
...
Рейтинг: 0 / 0
Кто-нибудь делал паскалевскую обертку над muPDF (libmuPDF.dll)?
    #38936921
Фотография Кроик Семён
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кроик СемёнdefecatorВ составе Chrome есть библиотека pdf.dll - в ней всё честно, и хидеры, и примеры использования можно найти по слову "Foxit PDF SDK DLL"

Эта библиотека даже не позволяет высоту страницы получить

P.S.

приходилось её вычислять "примерно" умножив ширину на sqrt(2).
Если укажешь высоту битмапа меньше чем нужно для страницы, то, если правильно помню, вызов функции RenderPDFPageToDC выводил белый квадрат
...
Рейтинг: 0 / 0
Кто-нибудь делал паскалевскую обертку над muPDF (libmuPDF.dll)?
    #38936933
Фотография Кроик Семён
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
P.P.S.

кстати, если пригодится, вот моя обертка для хромовской pdf.dll

MyChromePDFRender.pas
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
187.
188.
189.
190.
191.
192.
193.
194.
195.
196.
197.
198.
199.
200.
201.
202.
203.
204.
205.
206.
207.
208.
209.
210.
211.
212.
213.
214.
215.
216.
217.
218.
219.
220.
221.
222.
223.
224.
225.
226.
227.
228.
229.
230.
231.
232.
233.
234.
235.
236.
237.
238.
239.
240.
241.
242.
243.
244.
245.
246.
247.
248.
249.
250.
251.
252.
253.
254.
255.
256.
257.
258.
259.
260.
261.
262.
263.
264.
265.
266.
267.
268.
269.
270.
271.
272.
273.
274.
275.
276.
277.
278.
279.
280.
281.
282.
283.
284.
285.
286.
287.
288.
289.
290.
291.
292.
293.
294.
295.
296.
297.
298.
299.
300.
301.
302.
303.
304.
305.
306.
307.
308.
309.
310.
311.
312.
313.
314.
315.
316.
317.
318.
319.
320.
321.
322.
323.
324.
325.
326.
327.
328.
329.
330.
331.
332.
333.
334.
335.
336.
337.
338.
339.
340.
341.
342.
343.
344.
345.
346.
347.
348.
349.
350.
351.
352.
353.
354.
355.
356.
357.
358.
359.
360.
361.
362.
363.
364.
365.
366.
367.
368.
369.
370.
371.
372.
373.
374.
375.
376.
//Delphi wrapper for Google Chrome's "pdf.dll"
//Wrote by Simon Kroik, 06.2013
//Version 1.1
UNIT MyChromePDFRender;

INTERFACE
uses MyPDFRender, Windows, Classes, DB, Graphics, Types;

type
   TChromePDFBufferSize  = integer;

   TMyChromePDFRender = class(TCustomMyPDFRender)
   private
      FBuffer              : PChar;
      FBufferSize          : TChromePDFBufferSize;
      FPagesCount          : integer;
      FMaxPageWidthCm      : extended;
   protected
      procedure InitEmptyFields(); override;

      function GetPagesCount(): integer; override;
      function GetSizeInBytes(): int64; override;

      procedure AssignTo(Dest: TPersistent); override;
   public
      procedure Clear(); override;

      function SavePDFToStream(AStream: TStream): boolean; override;
      function LoadPDFFromStream(AStream: TStream; ALength: int64=0): boolean; override;

      procedure RenderPDFToBitmap(ABitmap: Graphics.TBitmap;
                                  APageNumber: integer;
                                  ADpiX: integer;
                                  ADpiY: integer;
                                  ADoAutoRotate: boolean;
                                  ADoCenterInBounds: boolean;
                                  ADoAutoSizeBitmap: boolean); override;

      procedure RenderPDFToCanvas(ACanvas: TCanvas;
                                  ARect: TRect;
                                  APageNumber: integer;
                                  ADpiX: integer;
                                  ADpiY: integer;
                                  ADoAutoRotate: boolean;
                                  ADoCenterInBounds: boolean); override;
   end;   
IMPLEMENTATION
uses SysUtils;
//##############################################################################
{ Utils }
//##############################################################################
//
// The "pdf.dll" has problems. For excample, LoadLibrary('pdf.dll') returns 0
// with the GetLastError() = 3221225614
//
// Hier found I the solution:
// http://stackoverflow.com/questions/3534572/delphi-loadlibrary-returns-0-lasterrorcde-3221225616-what-does-this-mean
//
// GetLastError() after LoadLibrary('pdf.dll') was "3221225614", not  "3221225616"
// but the solution from StackOverflow.com also works.
//
// The error code, 3221225616, seems, when asking Google, to be the result of an
// invalid floating point operation. Now, this seems very technical; indeed, what
// does loading a library have to do with floating point computations?
// The floating point control word (CW) is a bitfield where the bits specify how
// the processor should handle floating-point errors; it is actually rather
// common that unexpected floating point errors can be dealt with by changing
// one of these bits to 1 (which by the way is the default state). For an other
// example, see this question of mine, in which I get a totally unexpected
// division by zero error, which is dealt with by setting the "div by zero" bit
// of the control word to 1.
//
// var
//    SavedCW: word;
//
// ...
// SavedCW := Get8087CW;
// Set8087CW(SavedCW or $7);
// DLLHandle := LoadLibrary('3rdparty.dll');
// Set8087CW(SavedCW);
//
//------------------------------------------------------------------------------


const
   LibName  = 'pdf.dll';

type
   TGetPDFDocInfoProc = procedure(pdf_buffer       : PChar;
                                  buffer_size      : integer;
                                  page_count       : PInt;
                                  max_page_width   : PDouble
                                 ); cdecl;

   TRenderPDFPageToDCProc = procedure(pdf_buffer          : PChar;
                                      buffer_size         : integer;
                                      page_number         : integer;
                                      dc                  : HDC;
                                      dpi_x               : integer;
                                      dpi_y               : integer;
                                      bounds_origin_x     : integer;
                                      bounds_origin_y     : integer;
                                      bounds_width        : integer;
                                      bounds_height       : integer;
                                      fit_to_bounds       : boolean;
                                      stretch_to_bounds   : boolean;
                                      keep_aspect_ratio   : boolean;
                                      center_in_bounds    : boolean;
                                      autorotate          : boolean
                                     ); cdecl;

VAR
   internal_hLib : THandle;
   internal_procGetPDFDocInfo       : TGetPDFDocInfoProc;
   internal_procRenderPDFPageToDC   : TRenderPDFPageToDCProc;
//------------------------------------------------------------------------------
procedure BeforeCallDLL(out ASavedCW: word);
begin
   ASavedCW:=Get8087CW();
   Set8087CW(ASavedCW or $7); //see infos after "IMPLEMENTATION"
end;
//------------------------------------------------------------------------------
procedure AfterCallDLL(const ASavedCW: word);
begin
   Set8087CW(ASavedCW);
end;
//------------------------------------------------------------------------------
procedure FreeLib();
var
   iSavedCW  : word;
begin
   if internal_hLib<>0 then
   begin
      BeforeCallDLL(iSavedCW);
      try
         try
            FreeLibrary(internal_hLib);
         finally
            internal_hLib:=0;
         end;
      finally
         AfterCallDLL(iSavedCW);
      end;
   end; //if internal_hLib<>0
end;
//------------------------------------------------------------------------------
procedure RaiseLibLoadingException(const AMessage: string);
begin
   try
      FreeLib();
   finally
      raise EMyPDFRendererError.Create(
         'Library "'+LibName+'" is not correct loaded.'#13#10+AMessage
         );
   end;
end;
//------------------------------------------------------------------------------
function LoadLibIfNeed(): boolean;
var
   iSavedCW  : word;
   iLastErr : DWORD;
begin
   if internal_hLib=0 then
   begin
      BeforeCallDLL(iSavedCW);
      try
         internal_hLib:=LoadLibrary(LibName);
         iLastErr:=GetLastError();
      finally
         AfterCallDLL(iSavedCW);
      end;

      if internal_hLib=0 then
         RaiseLibLoadingException(SysErrorMessage(iLastErr))
      else
      begin
         @internal_procGetPDFDocInfo :=
            GetProcAddress(internal_hLib, 'GetPDFDocInfo');

         if not Assigned(@internal_procGetPDFDocInfo) then
            RaiseLibLoadingException('function "GetPDFDocInfo" is not found.');

         @internal_procRenderPDFPageToDC :=
            GetProcAddress(internal_hLib, 'RenderPDFPageToDC');

         if not Assigned(@internal_procRenderPDFPageToDC) then
            RaiseLibLoadingException('function "RenderPDFPageToDC" is not found.');
      end; //if internal_hLib<>0
   end;

   Result:=(internal_hLib<>0);
end;
//##############################################################################
{ TMyChromePDFRender }
//##############################################################################
function TMyChromePDFRender.GetPagesCount(): integer;
begin
   Result:=FPagesCount;
end;
//------------------------------------------------------------------------------
function TMyChromePDFRender.GetSizeInBytes(): int64;
begin
   Result:=FBufferSize;
end;
////////////////////////////////////////////////////////////////////////////////
procedure TMyChromePDFRender.InitEmptyFields();
begin
   inherited;

   FBuffer:=nil;
   FBufferSize:=0;
   FPagesCount:=0;
   FMaxPageWidthCm:=0;
end;
//------------------------------------------------------------------------------
procedure TMyChromePDFRender.Clear();
begin
   inherited;

   FreeMem(FBuffer);
   InitEmptyFields();
end;
//------------------------------------------------------------------------------
procedure TMyChromePDFRender.AssignTo(Dest: TPersistent);
var
   DstRender   : TMyChromePDFRender;
begin
   inherited;

   if Dest is TMyChromePDFRender then
   begin
      DstRender:=TMyChromePDFRender(Dest);

      DstRender.FBufferSize:=FBufferSize;
      DstRender.FPagesCount:=FPagesCount;
      DstRender.FMaxPageWidthCm:=FMaxPageWidthCm;

      GetMem(DstRender.FBuffer, DstRender.FBufferSize);
      Move(FBuffer^, DstRender.FBuffer^, DstRender.FBufferSize);
   end;
end;
//------------------------------------------------------------------------------
function TMyChromePDFRender.SavePDFToStream(AStream: TStream): boolean;
begin
   if FBufferSize>0 then
   begin
      AStream.Write(FBuffer^, FBufferSize);
      Result:=true;
   end
   else
      Result:=false;
end;
//------------------------------------------------------------------------------
function TMyChromePDFRender.LoadPDFFromStream(AStream: TStream;
   ALength: int64): boolean;
var
   iPDFSize                : int64;
   fMaxPageWidthPix72dpi   : double; //for WEB
   iSavedCW                : word;
begin
   if ALength>0 then
   begin
      iPDFSize:=ALength;

      if AStream.Position+iPDFSize > AStream.Size then
         raise EMyPDFRendererError.Create(
            'Length-Parameter is over the stream size'
            );
   end
   else
   begin
      iPDFSize:=AStream.Size - AStream.Position;
   end;

   if iPDFSize>High(TChromePDFBufferSize) then
      raise EMyPDFRendererError.Create(
         'PDF is too big: '+IntToStr(iPDFSize div (1024*1024))+' MB'
         );

   LoadLibIfNeed();

   Clear();

   FBufferSize:=iPDFSize;

   GetMem(FBuffer, FBufferSize);
   AStream.ReadBuffer(FBuffer^, FBufferSize);

   BeforeCallDLL(iSavedCW);
   try
      internal_procGetPDFDocInfo(FBuffer,
                                 FBufferSize,
                                 @FPagesCount,
                                 @fMaxPageWidthPix72dpi);
   finally
      AfterCallDLL(iSavedCW);
   end;

   FMaxPageWidthCm:=InchToCm(fMaxPageWidthPix72dpi/72.0);

   Result:=true;
end;
////////////////////////////////////////////////////////////////////////////////
procedure TMyChromePDFRender.RenderPDFToBitmap(ABitmap: TBitmap; APageNumber,
  ADpiX, ADpiY: integer; ADoAutoRotate: boolean; ADoCenterInBounds: boolean;
  ADoAutoSizeBitmap: boolean);
var
   iSavedCW : word;
begin
   LoadLibIfNeed();

   if ADoAutoSizeBitmap then
   begin
      ABitmap.Width:=CmToPixel(FMaxPageWidthCm, ADpiX);
      ABitmap.Height:=CmToPixel(FMaxPageWidthCm*sqrt(2), ADpiY);
   end;

   BeforeCallDLL(iSavedCW);
   try
      internal_procRenderPDFPageToDC(FBuffer,               // pdf_buffer
                                     FBufferSize,           // buffer_size
                                     APageNumber-1,         // page_number
                                     ABitmap.Canvas.Handle, // dc
                                     ADpiX,                 // dpi_x
                                     ADpiY,                 // dpi_y
                                     0,                     // bounds_origin_x
                                     0,                     // bounds_origin_y
                                     ABitmap.Width,         // bounds_width
                                     ABitmap.Height,        // bounds_height
                                     not ADoAutoSizeBitmap, // fit_to_bounds
                                     false,                 // stretch_to_bounds
                                     true,                  // keep_aspect_ratio
                                     ADoCenterInBounds,     // center_in_bounds
                                     ADoAutoRotate);        // autorotate
   finally
      AfterCallDLL(iSavedCW);
   end;
end;
//------------------------------------------------------------------------------
procedure TMyChromePDFRender.RenderPDFToCanvas(ACanvas: TCanvas; ARect: TRect;
  APageNumber, ADpiX, ADpiY: integer; ADoAutoRotate: boolean;
  ADoCenterInBounds: boolean);
var
   iSavedCW : word;
begin
   LoadLibIfNeed();

   BeforeCallDLL(iSavedCW);
   try
      internal_procRenderPDFPageToDC(FBuffer,               // pdf_buffer
                                     FBufferSize,           // buffer_size
                                     APageNumber-1,         // page_number
                                     ACanvas.Handle,        // dc
                                     ADpiX,                 // dpi_x
                                     ADpiY,                 // dpi_y
                                     ARect.Left,            // bounds_origin_x
                                     ARect.Top,             // bounds_origin_y
                                     ARect.Right-ARect.Left,// bounds_width
                                     ARect.Bottom-ARect.Top,// bounds_height
                                     true,                  // fit_to_bounds
                                     false,                 // stretch_to_bounds
                                     true,                  // keep_aspect_ratio
                                     ADoCenterInBounds,     // center_in_bounds
                                     ADoAutoRotate);        // autorotate
   finally
      AfterCallDLL(iSavedCW);
   end;
end;
////////////////////////////////////////////////////////////////////////////////

INITIALIZATION
   internal_hLib:=0;
FINALIZATION
   FreeLib();

END.



MyPDFRender.pas
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
187.
188.
189.
190.
191.
192.
193.
194.
195.
196.
197.
198.
199.
200.
UNIT MyPDFRender;

INTERFACE
uses Windows, SysUtils, Graphics, Classes, DB;

   function CmToInch(ACm: extended): extended;
   function InchToCm(AInch: extended): extended;
   function CmToPixel(ACm: extended; ADPI: integer): integer;
type
   EMyPDFRendererError = class(Exception)
   end;
   
   TCustomMyPDFRender = class(TPersistent)
   private
      FFullFileName        : string;

      procedure ReadDataProp(Stream: TStream);
      procedure WriteDataProp(Stream: TStream);
   protected
      procedure InitEmptyFields(); virtual;

      function GetPagesCount(): integer; virtual; abstract;
      function GetSizeInBytes(): int64; virtual; abstract;

      procedure AssignTo(Dest: TPersistent); override;
      procedure DefineProperties(Filer: TFiler); override;
   public
      constructor Create(); virtual;
      destructor Destroy(); override;

      procedure Clear(); virtual; abstract;

      function SavePDFToStream(AStream: TStream): boolean; virtual; abstract;
      function LoadPDFFromStream(AStream: TStream; ALength: int64=0): boolean; virtual; abstract;

      function LoadPDFFromFile(const APDFFile: string): boolean;
      function LoadPDFFromDB(AField: TField): boolean;
      function LoadPDFFromString(const APDFAsStringBuffer: string): boolean;

      procedure RenderPDFToBitmap(ABitmap: Graphics.TBitmap;
                                  APageNumber: integer;
                                  ADpiX: integer;
                                  ADpiY: integer;
                                  ADoAutoRotate: boolean;
                                  ADoCenterInBounds: boolean;
                                  ADoAutoSizeBitmap: boolean); virtual; abstract;

      procedure RenderPDFToCanvas(ACanvas: TCanvas;
                                  ARect: TRect;
                                  APageNumber: integer;
                                  ADpiX: integer;
                                  ADpiY: integer;
                                  ADoAutoRotate: boolean;
                                  ADoCenterInBounds: boolean); virtual; abstract;

      function IsEmpty(): boolean;
   public
      property PagesCount: integer read GetPagesCount;
      property FullFileName: string read FFullFileName;
      property SizeInBytes: int64 read GetSizeInBytes;
   end;

   TCustomMyPDFRenderClass = class of TCustomMyPDFRender;
                              
IMPLEMENTATION

////////////////////////////////////////////////////////////////////////////////
function CmToInch(ACm: extended): extended;
begin
   Result:=ACm/2.54;
end;
//------------------------------------------------------------------------------
function InchToCm(AInch: extended): extended;
begin
   Result:=AInch*2.54;
end;
//------------------------------------------------------------------------------
function CmToPixel(ACm: extended; ADPI: integer): integer;
var
   fInch : extended;
begin
   fInch:=CmToInch(ACm);
   Result:=Round(ADPI*fInch);
end;
//##############################################################################
{ TCustomMyPDFRender }
//##############################################################################
constructor TCustomMyPDFRender.Create();
begin
   InitEmptyFields();
end;
//------------------------------------------------------------------------------
destructor TCustomMyPDFRender.Destroy();
begin
   Clear();
   
   inherited;
end;
////////////////////////////////////////////////////////////////////////////////
procedure TCustomMyPDFRender.InitEmptyFields();
begin
   FFullFileName:='';
end;
//------------------------------------------------------------------------------
function TCustomMyPDFRender.IsEmpty(): boolean;
begin
   Result:=(GetPagesCount() = 0);
end;
////////////////////////////////////////////////////////////////////////////////
procedure TCustomMyPDFRender.DefineProperties(Filer: TFiler);
begin
   inherited;

   Filer.DefineBinaryProperty('Data',
                              ReadDataProp, WriteDataProp,
                              not IsEmpty());
end;
//------------------------------------------------------------------------------
procedure TCustomMyPDFRender.ReadDataProp(Stream: TStream);
begin
   LoadPDFFromStream(Stream);
end;
//------------------------------------------------------------------------------
procedure TCustomMyPDFRender.WriteDataProp(Stream: TStream);
begin
   SavePDFToStream(Stream);
end;
////////////////////////////////////////////////////////////////////////////////
procedure TCustomMyPDFRender.AssignTo(Dest: TPersistent);
var
   DstRender   : TCustomMyPDFRender;
begin
   if Dest is TCustomMyPDFRender then
   begin
      DstRender:=TCustomMyPDFRender(Dest);

      DstRender.Clear();
      DstRender.FFullFileName:=FFullFileName;
   end;
end;
//------------------------------------------------------------------------------
function TCustomMyPDFRender.LoadPDFFromFile(const APDFFile: string): boolean;
var
   F  : TFileStream;
begin
   if Trim(APDFFile)<>'' then
   begin
      F:=TFileStream.Create(APDFFile, fmOpenRead or fmShareDenyNone);
      try
         Result:=LoadPDFFromStream(F);

         if Result then
            FFullFileName:=APDFFile;
      finally
         FreeAndNil(F);
      end;
   end
   else
      Result:=false;
end;
//------------------------------------------------------------------------------
function TCustomMyPDFRender.LoadPDFFromDB(AField: TField): boolean;
var
   BLOBField   : TBLOBField;
   BLOBStream  : TStream;
begin
   if not Assigned(AField) then
      raise EMyPDFRendererError.Create('LoadPDFFromDB(Field=nil)');

   if not (AField is TBLOBField) then
      raise EMyPDFRendererError.Create('LoadPDFFromDB(Field<>TBLOBField)');

   BLOBField:=TBLOBField(AField);

   BLOBStream := AField.DataSet.CreateBlobStream(BLOBField, bmRead);
   try
      Result:=LoadPDFFromStream(BLOBStream);
   finally
      FreeAndNil(BLOBStream);
   end;
end;
//------------------------------------------------------------------------------
function TCustomMyPDFRender.LoadPDFFromString(
   const APDFAsStringBuffer: string): boolean;
var
   mem   : TMemoryStream;
begin
   mem:=TMemoryStream.Create();
   try
      mem.Write(PChar(APDFAsStringBuffer)^, Length(APDFAsStringBuffer));

      mem.Position:=0;
      Result:=LoadPDFFromStream(mem);
   finally
      FreeAndNil(mem);
   end;
end;
////////////////////////////////////////////////////////////////////////////////

END.


...
Рейтинг: 0 / 0
Период между сообщениями больше года.
Кто-нибудь делал паскалевскую обертку над muPDF (libmuPDF.dll)?
    #39435130
VolkodavSR
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Чуваки! Всем Здравия!

Может кому пригодится...
pdf.dll от хрома бывают разные. В одной из них нашел функцию "GetPDFPageSizeByIndex".
Вмонтировал ее в обёртку Кроик Семёна - ВСЕ РАБОТАЕТ! Размеры, и соответственно ориентация страниц pdf документа известны.
Огромное спасибо Кроик Семёну за его обертку!
Если что, ищете pdf.dll с этой функцией...
Параметры которые принимает эта функция TGetPDFPageSizeByIndexProc = procedure(pdf_buffer : PChar;
pdf_buffer_size : integer;
page_number : integer;
width : PDouble;
height : PDouble
); cdecl;

узнал где то здесь
Быть Добру!
...
Рейтинг: 0 / 0
Кто-нибудь делал паскалевскую обертку над muPDF (libmuPDF.dll)?
    #39435228
Фотография Кроик Семён
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
VolkodavSR,

надо же, как pdf.dll изменилась за эти годы.
...
Рейтинг: 0 / 0
Кто-нибудь делал паскалевскую обертку над muPDF (libmuPDF.dll)?
    #39611983
Фотография Кроик Семён
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Снова сошли руки до pdf.dll, начинаю дорабатывать обертку.

Для всех интересующихся темой PDF.DLL от Google Chrome вот немного информации:

1) как уже было сказано VolkodavSR двумя постами выше, существует расширенная версия PDF.DLL. Спустя многочасовое гугление удалось её найти здесь (я выложу далее, чтобы осталась здесь для истории). Скачал отсюда: https://www.dll.ru/files/pdf-dll.html (страшно, а вдруг с вирусом. Надо будет построить испытательный полигон, а так онлайн-антивирусы говорят что нормальная)

2) вот документация к DLLке, взял отсюда: https://chromium.googlesource.com/chromium/src/ /master/pdf/pdf.h
pdf.h
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef PDF_PDF_H_
#define PDF_PDF_H_
#include "build/build_config.h"
#if defined(OS_WIN)
#include <windows.h>
#endif
#if defined(OS_WIN)
typedef void (*PDFEnsureTypefaceCharactersAccessible)(const LOGFONT* font,
                                                      const wchar_t* text,
                                                      size_t text_length);
#endif
namespace chrome_pdf {
#if defined(OS_WIN)
// Printing modes - type to convert PDF to for printing
enum PrintingMode {
  kEmf = 0,
  kTextOnly = 1,
  kPostScript2 = 2,
  kPostScript3 = 3,
};
// |pdf_buffer| is the buffer that contains the entire PDF document to be
//     rendered.
// |buffer_size| is the size of |pdf_buffer| in bytes.
// |page_number| is the 0-based index of the page to be rendered.
// |dc| is the device context to render into.
// |dpi_x| and |dpi_y| is the resolution.
// |bounds_origin_x|, |bounds_origin_y|, |bounds_width| and |bounds_height|
//     specify a bounds rectangle within the DC in which to render the PDF
//     page.
// |fit_to_bounds| specifies whether the output should be shrunk to fit the
//     supplied bounds if the page size is larger than the bounds in any
//     dimension. If this is false, parts of the PDF page that lie outside
//     the bounds will be clipped.
// |stretch_to_bounds| specifies whether the output should be stretched to fit
//     the supplied bounds if the page size is smaller than the bounds in any
//     dimension.
// If both |fit_to_bounds| and |stretch_to_bounds| are true, then
//     |fit_to_bounds| is honored first.
// |keep_aspect_ratio| If any scaling is to be done is true, this flag
//     specifies whether the original aspect ratio of the page should be
//     preserved while scaling.
// |center_in_bounds| specifies whether the final image (after any scaling is
//     done) should be centered within the given bounds.
// |autorotate| specifies whether the final image should be rotated to match
//     the output bound.
// Returns false if the document or the page number are not valid.
bool RenderPDFPageToDC(const void* pdf_buffer,
                       int buffer_size,
                       int page_number,
                       HDC dc,
                       int dpi_x,
                       int dpi_y,
                       int bounds_origin_x,
                       int bounds_origin_y,
                       int bounds_width,
                       int bounds_height,
                       bool fit_to_bounds,
                       bool stretch_to_bounds,
                       bool keep_aspect_ratio,
                       bool center_in_bounds,
                       bool autorotate);
void SetPDFEnsureTypefaceCharactersAccessible(
    PDFEnsureTypefaceCharactersAccessible func);
void SetPDFUseGDIPrinting(bool enable);
void SetPDFUsePrintMode(int mode);
#endif  // defined(OS_WIN)
// |page_count| and |max_page_width| are optional and can be NULL.
// Returns false if the document is not valid.
bool GetPDFDocInfo(const void* pdf_buffer,
                   int buffer_size,
                   int* page_count,
                   double* max_page_width);
// Gets the dimensions of a specific page in a document.
// |pdf_buffer| is the buffer that contains the entire PDF document to be
//     rendered.
// |pdf_buffer_size| is the size of |pdf_buffer| in bytes.
// |page_number| is the page number that the function will get the dimensions
//     of.
// |width| is the output for the width of the page in points.
// |height| is the output for the height of the page in points.
// Returns false if the document or the page number are not valid.
bool GetPDFPageSizeByIndex(const void* pdf_buffer,
                           int pdf_buffer_size,
                           int page_number,
                           double* width,
                           double* height);
// Renders PDF page into 4-byte per pixel BGRA color bitmap.
// |pdf_buffer| is the buffer that contains the entire PDF document to be
//     rendered.
// |pdf_buffer_size| is the size of |pdf_buffer| in bytes.
// |page_number| is the 0-based index of the page to be rendered.
// |bitmap_buffer| is the output buffer for bitmap.
// |bitmap_width| is the width of the output bitmap.
// |bitmap_height| is the height of the output bitmap.
// |dpi_x| and |dpi_y| is the resolution.
// |autorotate| specifies whether the final image should be rotated to match
//     the output bound.
// Returns false if the document or the page number are not valid.
bool RenderPDFPageToBitmap(const void* pdf_buffer,
                           int pdf_buffer_size,
                           int page_number,
                           void* bitmap_buffer,
                           int bitmap_width,
                           int bitmap_height,
                           int dpi_x,
                           int dpi_y,
                           bool autorotate);
}  // namespace chrome_pdf
#endif  // PDF_PDF_H_




3) несколько лет назад Google открыл исходники библиотеки (правда под именем pdfium), так что если я правильно понимаю, либу стало возмжно клегально распространять с проектом. Вот статья на немецком: https://www.golem.de/news/google-chromes-pdf-renderer-ist-open-source-1405-106692.html

4) можно было бы воспользоваться новой библиотекой PDFIUM.DLL, но она уж сильно навороченная по сравнению с PDF.DLL, так что я этим путем не пойду, оставлю лишь здесь пару ссылок, чтобы мое гугление не пропало зря
пара ссылок про pdfium
скомпилированную версия pdfium.dll можно найти здесь: https://assendelft.webathome.org/Pdfium/

актуальная версия на сегодня, которая и на Win XP пойдет, эта: https://assendelft.webathome.org/Pdfium/2018-03-04/PdfiumViewer-x86-no_v8-no_xfa/pdfium.dll


Projekts:

https://github.com/pvginkel/PdfiumBuild

https://github.com/pvginkel/PdfiumViewer


Delphi-wrapper:

https://github.com/ahausladen/PdfiumLib/blob/master/Source/PdfiumLib.pas

...
Рейтинг: 0 / 0
Кто-нибудь делал паскалевскую обертку над muPDF (libmuPDF.dll)?
    #39611992
Фотография Кроик Семён
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Думал переименованным в JPEG архивчиком выложить, ан нет. Умный сайт. Не получится на SQL.RU разместить.
Даю ссылку на dropbox, постараюсь там не удалить случайно в следующие годы.

https://www.dropbox.com/sh/swzdcdimuo39fbu/AAAM1fltKGNHjm3RvAIAYZr2a?dl=0
...
Рейтинг: 0 / 0
Кто-нибудь делал паскалевскую обертку над muPDF (libmuPDF.dll)?
    #39612298
Фотография Кроик Семён
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Обертка для новой версии PDF.DLL готова. Выкладываю, вдруг кому-нибудь пригодится.

Version 2.0

MyPDFRender.pas
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
187.
188.
189.
190.
191.
192.
193.
194.
195.
196.
197.
198.
199.
200.
201.
202.
203.
204.
205.
206.
207.
208.
209.
210.
211.
212.
213.
214.
215.
216.
217.
218.
219.
220.
221.
222.
223.
224.
225.
226.
227.
228.
229.
230.
231.
232.
233.
234.
235.
236.
237.
238.
239.
240.
241.
242.
243.
244.
245.
246.
247.
248.
249.
250.
251.
252.
253.
254.
255.
256.
257.
258.
259.
260.
261.
262.
263.
264.
265.
266.
267.
268.
269.
270.
271.
272.
273.
274.
275.
276.
277.
278.
279.
280.
281.
282.
283.
284.
285.
286.
287.
288.
289.
290.
291.
292.
293.
294.
295.
296.
297.
298.
//Wrote by Simon Kroik, 06.2013-03.2018
//Tested with Delphi 6
UNIT MyPDFRender;

INTERFACE
uses Windows, SysUtils, Graphics, Classes, DB;

type
   EMyPDFRendererError = class(Exception)
   end;

type   
   TCustomMyPDFRender = class(TPersistent)
   private
      FFullFileName        : string;

      procedure ReadDataProp(Stream: TStream);
      procedure WriteDataProp(Stream: TStream);
   protected
      procedure InitEmptyFields(); virtual;

      function GetPagesCount(): integer; virtual; abstract;
      function GetSizeInBytes(): int64; virtual; abstract;

      procedure AssignTo(Dest: TPersistent); override;
      procedure DefineProperties(Filer: TFiler); override;

      procedure RaiseIfPageNumberWrong(APageNumber: integer);
   public
      constructor Create(); virtual;
      destructor Destroy(); override;

      procedure Clear(); virtual; abstract;

      function SavePDFToStream(AStream: TStream): boolean; virtual; abstract;
      function LoadPDFFromStream(AStream: TStream; ALength: int64=0): boolean; virtual; abstract;

      function LoadPDFFromFile(const APDFFile: string): boolean;
      function LoadPDFFromDB(AField: TField): boolean;
      function LoadPDFFromString(const APDFAsStringBuffer: string): boolean;

      function GetPageSizeInCm(APageNumber: integer;
                               var AWidthCm: extended;
                               var AHeightCm: extended): boolean; virtual; abstract;

      function GetPageSizeInPixel(APageNumber: integer;
                                  ADpiX: integer;
                                  ADpiY: integer;
                                  var AWidth: integer;
                                  var AHeight: integer): boolean; virtual; abstract;

      function RenderPDFToDC(ADC: HDC;
                             ARectLeft: integer;
                             ARectTop: integer;
                             ARectWidth: integer;
                             ARectHeight: integer;
                             APageNumber: integer;
                             ADpiX: integer;
                             ADpiY: integer;
                             ADoFitToBounds: boolean;
                             ADoStretchToBounds: boolean;
                             ADoKeepAspectRatio: boolean;
                             ADoCenterInBounds: boolean;
                             ADoAutoRotate: boolean): boolean; virtual; abstract;                                  

      function RenderPDFToCanvas(ACanvas: TCanvas;
                                 ARect: TRect;
                                 APageNumber: integer;
                                 ADpiX: integer;
                                 ADpiY: integer;
                                 ADoAutoRotate: boolean;
                                 ADoCenterInBounds: boolean): boolean; virtual;

      function RenderPDFToBitmap(ABitmap: Graphics.TBitmap;
                                 APageNumber: integer;
                                 ADpiX: integer;
                                 ADpiY: integer;
                                 ADoAutoRotate: boolean;
                                 ADoCenterInBounds: boolean;
                                 ADoAutoSizeBitmap: boolean): boolean; virtual;

      function IsEmpty(): boolean;
   public
      property PagesCount: integer read GetPagesCount;
      property FullFileName: string read FFullFileName;
      property SizeInBytes: int64 read GetSizeInBytes;
   end;

   TCustomMyPDFRenderClass = class of TCustomMyPDFRender;

//uitils   
   function CmToInch(ACm: extended): extended;
   function InchToCm(AInch: extended): extended;
   function CmToPixel(ACm: extended; ADPI: integer): integer;


IMPLEMENTATION

////////////////////////////////////////////////////////////////////////////////
function CmToInch(ACm: extended): extended;
begin
   Result:=ACm/2.54;
end;
//------------------------------------------------------------------------------
function InchToCm(AInch: extended): extended;
begin
   Result:=AInch*2.54;
end;
//------------------------------------------------------------------------------
function CmToPixel(ACm: extended; ADPI: integer): integer;
var
   fInch : extended;
begin
   fInch:=CmToInch(ACm);
   Result:=Round(ADPI*fInch);
end;
//##############################################################################
{ TCustomMyPDFRender }
//##############################################################################
constructor TCustomMyPDFRender.Create();
begin
   InitEmptyFields();
end;
//------------------------------------------------------------------------------
destructor TCustomMyPDFRender.Destroy();
begin
   Clear();
   
   inherited;
end;
////////////////////////////////////////////////////////////////////////////////
procedure TCustomMyPDFRender.InitEmptyFields();
begin
   FFullFileName:='';
end;
//------------------------------------------------------------------------------
function TCustomMyPDFRender.IsEmpty(): boolean;
begin
   Result:=(GetPagesCount() = 0);
end;
////////////////////////////////////////////////////////////////////////////////
procedure TCustomMyPDFRender.DefineProperties(Filer: TFiler);
begin
   inherited;

   Filer.DefineBinaryProperty('Data',
                              ReadDataProp, WriteDataProp,
                              not IsEmpty());
end;
//------------------------------------------------------------------------------
procedure TCustomMyPDFRender.ReadDataProp(Stream: TStream);
begin
   LoadPDFFromStream(Stream);
end;
//------------------------------------------------------------------------------
procedure TCustomMyPDFRender.WriteDataProp(Stream: TStream);
begin
   SavePDFToStream(Stream);
end;
////////////////////////////////////////////////////////////////////////////////
procedure TCustomMyPDFRender.AssignTo(Dest: TPersistent);
var
   DstRender   : TCustomMyPDFRender;
begin
   if Dest is TCustomMyPDFRender then
   begin
      DstRender:=TCustomMyPDFRender(Dest);

      DstRender.Clear();
      DstRender.FFullFileName:=FFullFileName;
   end;
end;
//------------------------------------------------------------------------------
function TCustomMyPDFRender.LoadPDFFromFile(const APDFFile: string): boolean;
var
   F  : TFileStream;
begin
   if Trim(APDFFile)<>'' then
   begin
      F:=TFileStream.Create(APDFFile, fmOpenRead or fmShareDenyNone);
      try
         Result:=LoadPDFFromStream(F);

         if Result then
            FFullFileName:=APDFFile;
      finally
         FreeAndNil(F);
      end;
   end
   else
      Result:=false;
end;
//------------------------------------------------------------------------------
function TCustomMyPDFRender.LoadPDFFromDB(AField: TField): boolean;
var
   BLOBField   : TBLOBField;
   BLOBStream  : TStream;
begin
   if not Assigned(AField) then
      raise EMyPDFRendererError.Create('LoadPDFFromDB(Field=nil)');

   if not (AField is TBLOBField) then
      raise EMyPDFRendererError.Create('LoadPDFFromDB(Field<>TBLOBField)');

   BLOBField:=TBLOBField(AField);

   BLOBStream := AField.DataSet.CreateBlobStream(BLOBField, bmRead);
   try
      Result:=LoadPDFFromStream(BLOBStream);
   finally
      FreeAndNil(BLOBStream);
   end;
end;
//------------------------------------------------------------------------------
function TCustomMyPDFRender.LoadPDFFromString(
   const APDFAsStringBuffer: string): boolean;
var
   mem   : TMemoryStream;
begin
   mem:=TMemoryStream.Create();
   try
      mem.Write(PChar(APDFAsStringBuffer)^, Length(APDFAsStringBuffer));

      mem.Position:=0;
      Result:=LoadPDFFromStream(mem);
   finally
      FreeAndNil(mem);
   end;
end;
////////////////////////////////////////////////////////////////////////////////
procedure TCustomMyPDFRender.RaiseIfPageNumberWrong(APageNumber: integer);
var
   iPagesCount   : integer;
begin
   iPagesCount := GetPagesCount();

   if iPagesCount<1 then
      EMyPDFRendererError.Create('There are 0 pageses in document')
   else
   if (APageNumber<1) or (APageNumber>iPagesCount) then
      EMyPDFRendererError.Create('Page-Number "'+IntToStr(APageNumber)+'" '+
                                 'is out of range [1..'+IntToStr(iPagesCount)+']');
end;
//------------------------------------------------------------------------------
function TCustomMyPDFRender.RenderPDFToCanvas(ACanvas: TCanvas; ARect: TRect;
  APageNumber, ADpiX, ADpiY: integer; ADoAutoRotate: boolean;
  ADoCenterInBounds: boolean): boolean;
begin
   Result:=RenderPDFToDC(ACanvas.Handle,           // ADC
                         ARect.Left,               // ARectLeft
                         ARect.Top,                // ARectTop
                         ARect.Right-ARect.Left,   // ARectWidth
                         ARect.Bottom-ARect.Top,   // ARectHeight
                         APageNumber,              // APageNumber
                         ADpiX,                    // ADpiX
                         ADpiY,                    // ADpiY
                         true,                     // ADoFitToBounds
                         false,                    // ADoStretchToBounds
                         true,                     // ADoKeepAspectRatio
                         ADoCenterInBounds,        // ADoCenterInBounds
                         ADoAutoRotate             // ADoAutoRotate
                         );

end;
//------------------------------------------------------------------------------
function TCustomMyPDFRender.RenderPDFToBitmap(ABitmap: Graphics.TBitmap;
  APageNumber, ADpiX, ADpiY: integer; ADoAutoRotate: boolean;
  ADoCenterInBounds: boolean; ADoAutoSizeBitmap: boolean): boolean;
var
   iW       : integer;
   iH       : integer;
begin
   if ADoAutoSizeBitmap then
   begin
      GetPageSizeInPixel(APageNumber, ADpiX, ADpiY, iW, iH);
      ABitmap.Width:=iW;
      ABitmap.Height:=iH;
   end;

   Result:=RenderPDFToDC(ABitmap.Canvas.Handle,    // ADC
                         0,                        // ARectLeft
                         0,                        // ARectTop
                         ABitmap.Width,            // ARectWidth
                         ABitmap.Height,           // ARectHeight
                         APageNumber,              // APageNumber
                         ADpiX,                    // ADpiX
                         ADpiY,                    // ADpiY
                         not ADoAutoSizeBitmap,    // ADoFitToBounds
                         false,                    // ADoStretchToBounds
                         true,                     // ADoKeepAspectRatio
                         ADoCenterInBounds,        // ADoCenterInBounds
                         ADoAutoRotate             // ADoAutoRotate
                         );


end;
//------------------------------------------------------------------------------
END.




MyChromePDFRender.pas
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
187.
188.
189.
190.
191.
192.
193.
194.
195.
196.
197.
198.
199.
200.
201.
202.
203.
204.
205.
206.
207.
208.
209.
210.
211.
212.
213.
214.
215.
216.
217.
218.
219.
220.
221.
222.
223.
224.
225.
226.
227.
228.
229.
230.
231.
232.
233.
234.
235.
236.
237.
238.
239.
240.
241.
242.
243.
244.
245.
246.
247.
248.
249.
250.
251.
252.
253.
254.
255.
256.
257.
258.
259.
260.
261.
262.
263.
264.
265.
266.
267.
268.
269.
270.
271.
272.
273.
274.
275.
276.
277.
278.
279.
280.
281.
282.
283.
284.
285.
286.
287.
288.
289.
290.
291.
292.
293.
294.
295.
296.
297.
298.
299.
300.
301.
302.
303.
304.
305.
306.
307.
308.
309.
310.
311.
312.
313.
314.
315.
316.
317.
318.
319.
320.
321.
322.
323.
324.
325.
326.
327.
328.
329.
330.
331.
332.
333.
334.
335.
336.
337.
338.
339.
340.
341.
342.
343.
344.
345.
346.
347.
348.
349.
350.
351.
352.
353.
354.
355.
356.
357.
358.
359.
360.
361.
362.
363.
364.
365.
366.
367.
368.
369.
370.
371.
372.
373.
374.
375.
376.
377.
378.
379.
380.
381.
382.
383.
384.
385.
386.
387.
388.
389.
390.
391.
392.
393.
394.
395.
396.
397.
398.
399.
400.
401.
402.
403.
404.
405.
406.
407.
408.
409.
410.
411.
412.
413.
414.
415.
416.
417.
418.
419.
420.
421.
422.
423.
424.
425.
426.
427.
428.
429.
430.
431.
432.
433.
434.
435.
436.
437.
438.
439.
440.
441.
442.
443.
444.
445.
446.
447.
448.
449.
450.
451.
452.
453.
454.
455.
456.
457.
458.
459.
460.
461.
462.
463.
464.
465.
466.
467.
468.
469.
470.
471.
472.
473.
474.
475.
476.
477.
//Delphi wrapper for Google Chrome's "pdf.dll" with GetPDFPageSizeByIndex()
//Wrote by Simon Kroik, 06.2013-03.2018
//Version 2.0
//Tested with Delphi 6 
UNIT MyChromePDFRender;

INTERFACE
uses MyPDFRender, Windows, Classes, DB, Graphics, Types;

type
   TChromePDFBufferSize  = integer;

   TMyChromePDFRender = class(TCustomMyPDFRender)
   private
      FBuffer              : PChar;
      FBufferSize          : TChromePDFBufferSize;
      FPagesCount          : integer;
      FMaxPageWidthCm      : extended;

   protected
      procedure InitEmptyFields(); override;

      function GetPagesCount(): integer; override;
      function GetSizeInBytes(): int64; override;

      procedure AssignTo(Dest: TPersistent); override;
   public
      procedure Clear(); override;

      function SavePDFToStream(AStream: TStream): boolean; override;
      function LoadPDFFromStream(AStream: TStream; ALength: int64=0): boolean; override;

      function GetPageSizeInCm(APageNumber: integer;
                               var AWidthCm: extended;
                               var AHeightCm: extended): boolean; override;

      function GetPageSizeInPixel(APageNumber: integer;
                                  ADpiX: integer;
                                  ADpiY: integer;
                                  var AWidth: integer;
                                  var AHeight: integer): boolean; override;

      function RenderPDFToDC(ADC: HDC;
                             ARectLeft: integer;
                             ARectTop: integer;
                             ARectWidth: integer;
                             ARectHeight: integer;
                             APageNumber: integer;
                             ADpiX: integer;
                             ADpiY: integer;
                             ADoFitToBounds: boolean;
                             ADoStretchToBounds: boolean;
                             ADoKeepAspectRatio: boolean;
                             ADoCenterInBounds: boolean;
                             ADoAutoRotate: boolean): boolean; override;

   public
      property MaxPageWidthCm: extended read FMaxPageWidthCm;
   end;
   
IMPLEMENTATION
uses SysUtils;
//##############################################################################
{ Utils }
//##############################################################################
//
// The "pdf.dll" has problems. For excample, LoadLibrary('pdf.dll') returns 0
// with the GetLastError() = 3221225614
//
// Hier found I the solution:
// http://stackoverflow.com/questions/3534572/delphi-loadlibrary-returns-0-lasterrorcde-3221225616-what-does-this-mean
//
// GetLastError() after LoadLibrary('pdf.dll') was "3221225614", not  "3221225616"
// but the solution from StackOverflow.com also works.
//
// The error code, 3221225616, seems, when asking Google, to be the result of an
// invalid floating point operation. Now, this seems very technical; indeed, what
// does loading a library have to do with floating point computations?
// The floating point control word (CW) is a bitfield where the bits specify how
// the processor should handle floating-point errors; it is actually rather
// common that unexpected floating point errors can be dealt with by changing
// one of these bits to 1 (which by the way is the default state). For an other
// example, see this question of mine, in which I get a totally unexpected
// division by zero error, which is dealt with by setting the "div by zero" bit
// of the control word to 1.
//
// var
//    SavedCW: word;
//
// ...
// SavedCW := Get8087CW;
// Set8087CW(SavedCW or $7);
// DLLHandle := LoadLibrary('3rdparty.dll');
// Set8087CW(SavedCW);
//
//------------------------------------------------------------------------------


const
   LibName  = 'pdf.dll';

type
   TGraphicCracker = class(Graphics.TGraphic);

type   
   TGetPDFDocInfoProc = procedure(pdf_buffer       : PChar;
                                  buffer_size      : integer;
                                  page_count       : PInt;
                                  max_page_width   : PDouble
                                 ); cdecl;

   TGetPDFPageSizeByIndexFunc = function(pdf_buffer          : PChar;
                                         buffer_size         : integer;
                                         page_number         : integer;
                                         width               : PDouble;
                                         height              : PDouble): BOOL; cdecl;

   TRenderPDFPageToDCFunc = function(pdf_buffer          : PChar;
                                     buffer_size         : integer;
                                     page_number         : integer;
                                     dc                  : HDC;
                                     dpi_x               : integer;
                                     dpi_y               : integer;
                                     bounds_origin_x     : integer;
                                     bounds_origin_y     : integer;
                                     bounds_width        : integer;
                                     bounds_height       : integer;
                                     fit_to_bounds       : boolean;
                                     stretch_to_bounds   : boolean;
                                     keep_aspect_ratio   : boolean;
                                     center_in_bounds    : boolean;
                                     autorotate          : boolean
                                    ): BOOL; cdecl;

VAR
   internal_hLib                       : THandle;
   internal_procGetPDFDocInfo          : TGetPDFDocInfoProc;
   internal_funcGetPDFPageSizeByIndex  : TGetPDFPageSizeByIndexFunc;
   internal_funcRenderPDFPageToDC      : TRenderPDFPageToDCFunc;
//------------------------------------------------------------------------------
procedure BeforeCallDLL(out ASavedCW: word);
begin
   ASavedCW:=Get8087CW();
   Set8087CW(ASavedCW or $7); //see infos after "IMPLEMENTATION"
end;
//------------------------------------------------------------------------------
procedure AfterCallDLL(const ASavedCW: word);
begin
   Set8087CW(ASavedCW);
end;
//------------------------------------------------------------------------------
procedure FreeLib();
var
   iSavedCW  : word;
begin
   if internal_hLib<>0 then
   begin
      BeforeCallDLL(iSavedCW);
      try
         try
            FreeLibrary(internal_hLib);
         finally
            internal_hLib:=0;
         end;
      finally
         AfterCallDLL(iSavedCW);
      end;
   end; //if internal_hLib<>0
end;
//------------------------------------------------------------------------------
procedure RaiseLibLoadingException(const AMessage: string);
begin
   try
      FreeLib();
   finally
      raise EMyPDFRendererError.Create(
         'Library "'+LibName+'" is not correct loaded.'#13#10+AMessage
         );
   end;
end;
//------------------------------------------------------------------------------
function LoadLibIfNeed(): boolean;
var
   iSavedCW  : word;
   iLastErr : DWORD;
begin
   if internal_hLib=0 then
   begin
      BeforeCallDLL(iSavedCW);
      try
         internal_hLib:=LoadLibrary(LibName);
         iLastErr:=GetLastError();
      finally
         AfterCallDLL(iSavedCW);
      end;

      if internal_hLib=0 then
         RaiseLibLoadingException(SysErrorMessage(iLastErr))
      else
      begin
         //-- GetPDFDocInfo --
         @internal_procGetPDFDocInfo :=
            GetProcAddress(internal_hLib, 'GetPDFDocInfo');

         if not Assigned(@internal_procGetPDFDocInfo) then
            RaiseLibLoadingException('function "GetPDFDocInfo" is not found.');

         //-- GetPDFPageSizeByIndex --
         @internal_funcGetPDFPageSizeByIndex :=
            GetProcAddress(internal_hLib, 'GetPDFPageSizeByIndex');

         if not Assigned(@internal_funcGetPDFPageSizeByIndex) then
            RaiseLibLoadingException('function "GetPDFPageSizeByIndex" is not found.');

         //-- RenderPDFPageToDC --
         @internal_funcRenderPDFPageToDC :=
            GetProcAddress(internal_hLib, 'RenderPDFPageToDC');

         if not Assigned(@internal_funcRenderPDFPageToDC) then
            RaiseLibLoadingException('function "RenderPDFPageToDC" is not found.');

         // >>> not used Function from DLL: RenderPDFPageToBitmap() 
                     
      end; //if internal_hLib<>0
   end;

   Result:=(internal_hLib<>0);
end;
//##############################################################################
{ TMyChromePDFRender }
//##############################################################################
function TMyChromePDFRender.GetPagesCount(): integer;
begin
   Result:=FPagesCount;
end;
//------------------------------------------------------------------------------
function TMyChromePDFRender.GetSizeInBytes(): int64;
begin
   Result:=FBufferSize;
end;
////////////////////////////////////////////////////////////////////////////////
procedure TMyChromePDFRender.InitEmptyFields();
begin
   inherited;

   FBuffer:=nil;
   FBufferSize:=0;
   FPagesCount:=0;
   FMaxPageWidthCm:=0;
end;
//------------------------------------------------------------------------------
procedure TMyChromePDFRender.Clear();
begin
   inherited;

   FreeMem(FBuffer);
   InitEmptyFields();
end;
//------------------------------------------------------------------------------
procedure TMyChromePDFRender.AssignTo(Dest: TPersistent);
var
   DstRender   : TMyChromePDFRender;
begin
   inherited;

   if Dest is TMyChromePDFRender then
   begin
      DstRender:=TMyChromePDFRender(Dest);

      DstRender.FBufferSize:=FBufferSize;
      DstRender.FPagesCount:=FPagesCount;
      DstRender.FMaxPageWidthCm:=FMaxPageWidthCm;

      GetMem(DstRender.FBuffer, DstRender.FBufferSize);
      Move(FBuffer^, DstRender.FBuffer^, DstRender.FBufferSize);
   end;
end;
//------------------------------------------------------------------------------
function TMyChromePDFRender.SavePDFToStream(AStream: TStream): boolean;
begin
   if FBufferSize>0 then
   begin
      AStream.Write(FBuffer^, FBufferSize);
      Result:=true;
   end
   else
      Result:=false;
end;
//------------------------------------------------------------------------------
function TMyChromePDFRender.LoadPDFFromStream(AStream: TStream;
   ALength: int64): boolean;
var
   iPDFSize                : int64;
   fMaxPageWidthPix72dpi   : double; //for WEB
   iSavedCW                : word;
begin
   if ALength>0 then
   begin
      iPDFSize:=ALength;

      if AStream.Position+iPDFSize > AStream.Size then
         raise EMyPDFRendererError.Create(
            'Length-Parameter is over the stream size'
            );
   end
   else
   begin
      iPDFSize:=AStream.Size - AStream.Position;
   end;

   if iPDFSize>High(TChromePDFBufferSize) then
      raise EMyPDFRendererError.Create(
         'PDF is too big: '+IntToStr(iPDFSize div (1024*1024))+' MB'
         );

   LoadLibIfNeed();

   Clear();

   FBufferSize:=iPDFSize;

   GetMem(FBuffer, FBufferSize);
   AStream.ReadBuffer(FBuffer^, FBufferSize);

   BeforeCallDLL(iSavedCW);
   try
      internal_procGetPDFDocInfo(FBuffer,
                                 FBufferSize,
                                 @FPagesCount,
                                 @fMaxPageWidthPix72dpi);
   finally
      AfterCallDLL(iSavedCW);
   end;

   FMaxPageWidthCm:=InchToCm(fMaxPageWidthPix72dpi/72.0);

   Result:=true;
end;
////////////////////////////////////////////////////////////////////////////////
function TMyChromePDFRender.GetPageSizeInCm(APageNumber: integer;
  var AWidthCm: extended; var AHeightCm: extended): boolean;
var
   iSavedCW                : word;
   fWidthPix72dpi          : double; //for WEB
   fHeightPix72dpi         : double; //for WEB
begin
   LoadLibIfNeed();

   RaiseIfPageNumberWrong(APageNumber);

   BeforeCallDLL(iSavedCW);
   try
      // From: https://chromium.googlesource.com/chromium/src/+/master/pdf/pdf.h
      //
      // Gets the dimensions of a specific page in a document.
      // |pdf_buffer| is the buffer that contains the entire PDF document to be
      //     rendered.
      // |pdf_buffer_size| is the size of |pdf_buffer| in bytes.
      // |page_number| is the page number that the function will get the dimensions
      //     of.
      // |width| is the output for the width of the page in points.
      // |height| is the output for the height of the page in points.
      // Returns false if the document or the page number are not valid.

      Result:=internal_funcGetPDFPageSizeByIndex(FBuffer,          // pdf_buffer
                                                 FBufferSize,      // buffer_size
                                                 APageNumber-1,    // page_number
                                                 @fWidthPix72dpi,  // width
                                                 @fHeightPix72dpi);// height

      AWidthCm:=InchToCm(fWidthPix72dpi/72.0);
      AHeightCm:=InchToCm(fHeightPix72dpi/72.0);
   finally
      AfterCallDLL(iSavedCW);
   end;
end;
//------------------------------------------------------------------------------
function TMyChromePDFRender.GetPageSizeInPixel(APageNumber: integer;
  ADpiX: integer; ADpiY: integer; var AWidth: integer;
  var AHeight: integer): boolean;
var
   iSavedCW                : word;
   fWidthPix72dpi          : double; //for WEB
   fHeightPix72dpi         : double; //for WEB
begin
   LoadLibIfNeed();

   RaiseIfPageNumberWrong(APageNumber);

   BeforeCallDLL(iSavedCW);
   try
      Result:=internal_funcGetPDFPageSizeByIndex(FBuffer,          // pdf_buffer
                                                 FBufferSize,      // buffer_size
                                                 APageNumber-1,    // page_number
                                                 @fWidthPix72dpi,  // width
                                                 @fHeightPix72dpi);// height

      AWidth:=Round(fWidthPix72dpi/72.0*ADpiX);
      AHeight:=Round(fHeightPix72dpi/72.0*ADpiY);
   finally
      AfterCallDLL(iSavedCW);
   end;
end;
//------------------------------------------------------------------------------
function TMyChromePDFRender.RenderPDFToDC(ADC: HDC;
  ARectLeft, ARectTop, ARectWidth, ARectHeight: integer; APageNumber: integer;
  ADpiX, ADpiY: integer; ADoFitToBounds: boolean; ADoStretchToBounds: boolean;
  ADoKeepAspectRatio: boolean; ADoCenterInBounds: boolean;
  ADoAutoRotate: boolean): boolean;
var
   iSavedCW : word;
begin
   LoadLibIfNeed();

   RaiseIfPageNumberWrong(APageNumber);

   BeforeCallDLL(iSavedCW);
   try
      // From: https://chromium.googlesource.com/chromium/src/+/master/pdf/pdf.h
      //
      // |pdf_buffer| is the buffer that contains the entire PDF document to be
      //     rendered.
      // |buffer_size| is the size of |pdf_buffer| in bytes.
      // |page_number| is the 0-based index of the page to be rendered.
      // |dc| is the device context to render into.
      // |dpi_x| and |dpi_y| are the x and y resolutions respectively. If either
      //     value is -1, the dpi from the DC will be used.
      // |bounds_origin_x|, |bounds_origin_y|, |bounds_width| and |bounds_height|
      //     specify a bounds rectangle within the DC in which to render the PDF
      //     page.
      // |fit_to_bounds| specifies whether the output should be shrunk to fit the
      //     supplied bounds if the page size is larger than the bounds in any
      //     dimension. If this is false, parts of the PDF page that lie outside
      //     the bounds will be clipped.
      // |stretch_to_bounds| specifies whether the output should be stretched to fit
      //     the supplied bounds if the page size is smaller than the bounds in any
      //     dimension.
      // If both |fit_to_bounds| and |stretch_to_bounds| are true, then
      //     |fit_to_bounds| is honored first.
      // |keep_aspect_ratio| If any scaling is to be done is true, this flag
      //     specifies whether the original aspect ratio of the page should be
      //     preserved while scaling.
      // |center_in_bounds| specifies whether the final image (after any scaling is
      //     done) should be centered within the given bounds.
      // |autorotate| specifies whether the final image should be rotated to match
      //     the output bound.
      // Returns false if the document or the page number are not valid.   


      Result:=internal_funcRenderPDFPageToDC(FBuffer,               // pdf_buffer
                                             FBufferSize,           // buffer_size
                                             APageNumber-1,         // page_number
                                             ADC,                   // dc
                                             ADpiX,                 // dpi_x
                                             ADpiY,                 // dpi_y
                                             ARectLeft,             // bounds_origin_x
                                             ARectTop,              // bounds_origin_y
                                             ARectWidth,            // bounds_width
                                             ARectHeight,           // bounds_height
                                             ADoFitToBounds,        // fit_to_bounds
                                             ADoStretchToBounds,    // stretch_to_bounds
                                             ADoKeepAspectRatio,    // keep_aspect_ratio
                                             ADoCenterInBounds,     // center_in_bounds
                                             ADoAutoRotate);        // autorotate
   finally
      AfterCallDLL(iSavedCW);
   end;

end;
////////////////////////////////////////////////////////////////////////////////

INITIALIZATION
   internal_hLib:=0;
FINALIZATION
   FreeLib();

END.




пример использования
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
uses ... MyPDFRender, MyChromePDFRender

...

procedure TMainForm.ShowInfos(APdf: TCustomMyPDFRender; APageNr: integer;
   ADpiX, ADpiY: integer);
var
   fWidthCm       : extended;
   fHeightCm      : extended;
   iWidthPixel    : integer;
   iHeightPixel   : integer;

   sPageInfo      : string;
   sSizeInCm      : string;
   sSizeInPixel   : string;
begin
   APdf.GetPageSizeInCm(APageNr, fWidthCm, fHeightCm);
   APdf.GetPageSizeInPixel(APageNr, ADpiX, ADpiY, iWidthPixel, iHeightPixel);

   sPageInfo := 'Page '+IntToStr(APageNr)+' from '+IntToStr(APdf.PagesCount);
   sSizeInCm := '(W:'+FormatFloat('0.00',fWidthCm)+'cm  / '+
                'H:'+FormatFloat('0.00',fHeightCm)+'cm)';
   sSizeInPixel:='(W:'+IntToStr(iWidthPixel)+'pix ['+IntToStr(ADpiX)+'dpi]'+'  / '+
                 'H:'+IntToStr(iHeightPixel)+'pix ['+IntToStr(ADpiY)+'dpi])';

   //-- lblInfos: TLabel;
   lblInfos.Caption:=sPageInfo+#13#10+
                     sSizeInCm+#13#10+
                     sSizeInPixel;
end;
//------------------------------------------------------------------------------
procedure TMainForm.btnLoadPDFClick(Sender: TObject);
var
   pdf            : TCustomMyPDFRender;
   sAppPath       : string;
   sOutputPath    : string;
   iPageNr        : integer;
   iDpiX          : integer;
   iDpiY          : integer;
begin
   sAppPath:=ExtractFilePath(Application.ExeName);
   sOutputPath:=sAppPath+'BMP-OUTPUT\';

   iPageNr:=2;
   iDpiX:=200;
   iDpiY:=200;

   pdf := TMyChromePDFRender.Create();
   try
      if pdf.LoadPDFFromFile(sAppPath + 'test-document.pdf') then
      begin
         ShowInfos(pdf, iPageNr, iDpiX, iDpiY);

         //-- imgPDF: TImage;
         pdf.RenderPDFToBitmap(imgPDF.Picture.Bitmap, iPageNr, iDpiX, iDpiY, true, false, true);

         imgPDF.Picture.Bitmap.SaveToFile(sAppPath+'BMP-OUTPUT\test-bitmap-export.bmp');

      end;
   finally
      FreeAndNil(pdf);
   end;
end;
...
Рейтинг: 0 / 0
Кто-нибудь делал паскалевскую обертку над muPDF (libmuPDF.dll)?
    #39612803
чччД
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кроик Семён,

огромное спасибо!
...
Рейтинг: 0 / 0
Кто-нибудь делал паскалевскую обертку над muPDF (libmuPDF.dll)?
    #39612826
Фотография Кроик Семён
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
P.S.
забыл про одну фичу сказать: компонент возможно использовать как свойство другого комрпонента, причем загруженный в него в design-time pdf-файл отлично сохранится в ресурсы (dfm, например).

Зачем? Ну, например, в качестве векторного аналога TPicture.
...
Рейтинг: 0 / 0
Кто-нибудь делал паскалевскую обертку над muPDF (libmuPDF.dll)?
    #39612828
Фотография Кроик Семён
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
У меня сделан такой для Fastreport'a. Круто?
...
Рейтинг: 0 / 0
Кто-нибудь делал паскалевскую обертку над muPDF (libmuPDF.dll)?
    #39619448
Фотография Кроик Семён
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Создал новый топик по обертке ( ChromePDFRendererForDelphi - обертка для PDF.DLL от Google Chrome ).
Если будут вопросы, просьба там. А этот топик путь останется про muPDF .
...
Рейтинг: 0 / 0
20 сообщений из 20, страница 1 из 1
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Кто-нибудь делал паскалевскую обертку над muPDF (libmuPDF.dll)?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]