Print Page | Close Window

Metafile to PDF

Printed From: Debenu Quick PDF Library - PDF SDK Community Forum
Category: For Users of the Library
Forum Name: I need help - I can help
Forum Description: Problems and solutions while programming with the Debenu Quick PDF Library and Debenu PDF Viewer SDK
URL: http://www.quickpdf.org/forum/forum_posts.asp?TID=2741
Printed Date: 10 Jun 25 at 8:08AM
Software Version: Web Wiz Forums 11.01 - http://www.webwizforums.com


Topic: Metafile to PDF
Posted By: tushar
Subject: Metafile to PDF
Date Posted: 26 Sep 13 at 12:17PM
I am using QuickPDF trial version 09.16. I am using this library in Delphi XE2 (update 4). I wanted to create PDF from existing set of metafiles which are created runtime. Here is method which I am using to create new PDF file, but I am getting following error at highlighted red line.
 
Project PrintingDemo.exe raised exception class EInvalidGraphic with message 'Metafile is not valid'.
 
============================================================
procedure TForm1.prCreatePDFByQuickPDF(pMFList: TList);
var
  QP: TDebenuPDFLibrary0916;
  li, lj, lx: Integer;
  lMF: TMetafile;
  lCount: Integer;
  st: TMemoryStream;
begin
  QP := TDebenuPDFLibrary0916.Create;
  try
    if pMFList.Count > 0 then
    begin
      for li := 0 to pMFList.Count - 1 do
      begin
        lMF := pMFList.Items
  • ;
            st := TMemoryStream.Create;
            lMF.SaveToStream(st);
            st.Position := 0;
            QP.insertPages(li + 1, 1);
            QP.ImportEMFFromStream(st, 1, 1);
          end;
        end;
        QP.SaveToFile('C:\temp\QuickPDFTest.pdf');
      finally
        QP.Free;
      end;
    end;



  • Replies:
    Posted By: AndrewC
    Date Posted: 30 Sep 13 at 7:49AM
    tushar,

    Are you calling QP.UnlockKey with your trial key ?  You would need to do this after the call to Create.  This will unlock the library and you should find the EMF file will convert.

    If this is still an issue then you may need to create a support case by sending your questions and the EMF file to support@debenu.com

    Andrew.


    Posted By: HNRSoftware
    Date Posted: 01 Oct 13 at 10:03PM
    Andrew - I think you are correct.  The unlock key is probably the source of the actual error.

     I had fun converting his code to something I understood, but then had to figure out what an "imported EMF" was actually good for.  By trial and error and the reference help (and some luck), I figured out that "adding" an emf, or any image, doesn't actually do anything useful - you then need to "select" it  and "draw" it.  This suggests to me that tushar's code needed to either be calling drawimage immediately, or be keeping track of imageids for later use.  Very entertaining exercise.


    Posted By: AndrewC
    Date Posted: 02 Oct 13 at 1:08PM
    Hello,

    I came up with the following code that generated a valid PDF from a Delphi TCanvas object.

    procedure TfrmMainForm.prCreatePDFByQuickPDF(pMFList: TList);

    var
      QP: TDebenuPDFLibrary0916;
      ret, page: Integer;
    begin
      QP := TDebenuPDFLibrary0916.Create;
      ret := QP.UnlockKey(‘<insert your key here>’);
      if (ret <> 1) then
      begin
        ShowMessage(‘QPL DLL not loaded’);
        Exit;
      end;

      page := 1; 

      uCanvas := TCanvas.Create;
      uCanvas.Handle := QP.GetCanvasDC(612, 792); // Let DQPL provide the handle. 

      Arial10 := TFont.Create;
      Arial10.Name := ‘Arial’; 
      Arial10.Height := -10; 

      uCanvas.Font := Arial10; 
      uCanvas.TextOut(100, 100, ‘This is text from meta file’); 

      if (Page = 1) then
        QP.LoadFromCanvasDC(72, 0)           // Now generate the PDF file.onto page 1 
      else
        QP.NewPageFromCanvasDC(72, 0);   // Add a new page if page >= 2

      QP.SaveToFile(‘out.pdf’);
      uCanvas.Free;
      QP.Free;

    end;


    Andrew.



    Posted By: HNRSoftware
    Date Posted: 02 Oct 13 at 1:57PM
    Hi Andrew - great example, but I think it belongs on the other thread about Get/LoadFromCanvasDC.  From what little I know about "emf" files, your string " ‘This is text from meta file’"  doesn't have a lot of meaning for the example.  Without actually executing the code, it seems to me like it should produce a single page pdf file with that text line in it, page 2 never gets invoked.  Regardless, it helps me a great deal, I think I understand your point.  Howard


    Posted By: tushar
    Date Posted: 03 Oct 13 at 7:23AM

    Unfortunately suggestions given by Andrew is not working. Using QP.UnlockKey doesn’t help. I quit agree with HNR software about the use of ImportEMF functionality. I also feel that " I figured out that "adding" an emf, or any image, doesn't actually do anything useful "

     
    Also code sample given by Andrew uses Canvas Handle of QP component. It might result in different output. When creating metafile canvas we are using Printer handle. This may get different result and to make compatible with QP component there will be big efforts in existing code.


    Posted By: AndrewC
    Date Posted: 03 Oct 13 at 9:47AM
    Based on your original code here is another option to import the EMF files and then draw them onto the PDF file.  This code will handle the creation of new pages for each image in the list.  By default DQPL creates the 1st page by default so it is not required to call QP.NewPage.

    Here is some code to import a PDF file from a list of TList of MetaFiles.  The code could be change easily to import a list of EMF files from disk also.

    procedure TfrmMainForm.prCreatePDFByQuickPDF(pMFList: TList);
    var
      QP: TDebenuPDFLibrary0916;
      ret: Integer;
      I, id: Integer;

    begin
      QP := TDebenuPDFLibrary0916.Create;
      ret := QP.UnlockKey('< Put your license key here >');
      if (ret <> 1) then
      begin
        ShowMessage('QPL DLL not loaded');
        Exit;
      end;

      for I := 0 to pMFList.Count - 1 do
      begin
        id := QP.AddImageFromStream(TStream(pMFList), 0);

        if (I <> 0) then     // Do not add the 1st page it is created by default.
          QP.NewPage();

        QP.SetPageDimensions(QP.ImageWidth(), QP.ImageHeight());
        QP.SetOrigin(1);
        QP.DrawImage(0, 0, QP.ImageWidth(), QP.ImageHeight());
      end;

      QP.SaveImageToFile('output.pdf');
      QP.Free;
    end;



    Posted By: HNRSoftware
    Date Posted: 03 Oct 13 at 1:49PM
    Here is a simpler, somewhat relevant, piece of code that worked for me.  I really don't know or use emf files, so I just searched windows and found an emf file to see what happens.  This produced a pdf file with what would appear to be the proper emf drawn into a 2"x2" block, which is what I would expect from the help file.

    Note - TQuickPDF is my intercepted/extended usage of the TQuickPDF class, so Create does some additional setup.  You reference "dll not loaded" -- my arrangement doesn't use the dll.  I'm assuming you have some QuickPDF code somewhere that does do something correctly - a "Hello World" class of pdf file creation.  I try to make it a point of starting with something that does something simple correctly before trying the fancy stuff. 


    Function  EMFTest(EMFfname : string) : string;
    var QP    : TQuickPDF;
        pdffn : string;
        err   : Integer;
        lMF   : TMetafile;
        lCount: Integer;
        st: TMemoryStream;
         begin
         pdffn := 'EMFTest.pdf';
         QP := TQuickPDF.Create('');
         try
            if (QP.UnlockKey(QPDF_LicenseKey) <> 1) then logit('QuickPDF license key problem ['+QPDF_LicenseKey+']');
            QP.SetOrigin(1);                                // TOP LEFT - default is 0=BOTTOM LEFT
            QP.SetMeasurementUnits(2);            //2=Inches
            if FileExists(EMFfname) then
                 begin
                 lMF := TMetaFile.Create;
                 try
                    lMF.LoadFromFile(EMFfname);
                    st := TMemoryStream.Create;
                    lMF.SaveToStream(st);
                    st.Position := 0;
                    QP.ImportEMFFromStream(st, 1, 1);
                    QP.DrawImage(1.00,1.00,2.00,2.00);  //draws on currently selected page
                 finally
                    st.Free;
                    lMF.Free;
                    end; // of try
                 end;
            QP.SaveToFile(pdffn);
         finally
            result := 'EMFTest ['+pdffn+']  '+fileinfostr(pdffn);
            QP.Free;
            end;  // of try
         end;


    Posted By: AndrewC
    Date Posted: 04 Oct 13 at 10:21AM
    Here is some tested code that creates a MetaFile in memory, saves it to a MemoryStream and then DQPL loads the metafile and converts it to a PDF file.

    unit MainForm;

    interface

    uses
      Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
      System.Classes, Vcl.Graphics,
      Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, DebenuPDFLibrary0916,
      Printers;

    type
      TfrmMainForm = class(TForm)
        btnPDFByQuickPDF: TButton;
        procedure btnPDFByQuickPDFClick(Sender: TObject);
      private
        { Private declarations }
        procedure prCreatePDFByQuickPDF(pMFList: TList);
      public
        { Public declarations }
      end;

    var
      frmMainForm: TfrmMainForm;
      uCanvas: TCanvas;
      MyMetafile: TMetafile;
      uMFList: TList;

    implementation

    {$R *.dfm}

    procedure TfrmMainForm.btnPDFByQuickPDFClick(Sender: TObject);
    var
      List: TList;
      MF: TMetaFile;
      st: TMemorystream;
    begin

      List := TList.Create;
      MF := TMetaFile.Create;

      MF.MMWidth := 21000;   // A4
      MF.MMHeight := 29700;
      MF.Enhanced := True;

      uCanvas := TMetaFileCanvas.Create(MF, GetDC(Handle));  // Also works with Printer.Handle
      uCanvas.TextOut(100, 100, 'This is text from meta file');
      uCanvas.Rectangle(90, 90, 200, 30);
      uCanvas.Free;

      st := TMemorystream.Create;
      MF.SaveToStream(st);
      st.Position := 0;

      List.Add(st);

      prCreatePDFByQuickPDF(List);
    end;

    procedure TfrmMainForm.prCreatePDFByQuickPDF(pMFList: TList);
    var
      QP: TDebenuPDFLibrary0916;
      ret: Integer;
      I, id: Integer;
      dpix, dpiy: Integer;
      xx, yy: Integer;
      ImageWidthInPoints, ImageHeightInPoints: Double;
    begin
      QP := TDebenuPDFLibrary0916.Create;
      ret := QP.UnlockKey('<insert license key here>');
      if (ret <> 1) then
      begin
        ShowMessage('QPL DLL not loaded');
        Exit;
      end;

      for I := 0 to pMFList.Count - 1 do
      begin

        id := QP.AddImageFromStream(TMemoryStream(pMFList), 0);
        QP.SelectImage(id);

        if (I <> 0) then     // Do not add the 1st page it is created by default.
          QP.NewPage();

        QP.SetOrigin(1);
        QP.SetPageDimensions(QP.ImageWidth(), QP.ImageHeight());
        QP.DrawImage(0, 0, QP.ImageWidth(), QP.ImageHeight());
      end;

      QP.SaveToFile('out.pdf');
      QP.Free;
    end;

    end.



    Print Page | Close Window

    Forum Software by Web Wiz Forums® version 11.01 - http://www.webwizforums.com
    Copyright ©2001-2014 Web Wiz Ltd. - http://www.webwiz.co.uk