New Blog Post: PDF/A and Metadata

Set DPI value in TppPNGDevice without _1 file

We have a problem with TppPNGDevice. If we do not specify OutputStream, the TPPReport.PrintToDevices saves a file named"_1" at the execution location. Unfortunately, this is not a good solution because our application is started several times in certain constellations and the following error occurs repeatedly: File "C:\Daten\Apps\Loader\_1" cannot be created. The process cannot access the file because it is being used by another process.
However, if we specify OutputStream (PngDevice.OutputStream := MemStream), the set DPI value is not included in the output image.
This is probably due to the different assignments of the image to the TppPNGDevice.
If the DPI value is specified, we use TPngDevice.PNG.SaveToStream(MemStream). This is how the DPI assignment works if the OutputStream is not set.
If the DPI value is not specified, we use MemStream := (PngDevice.OutputStream As TMemoryStream).

Long story short: How can we specify the DPI value for a TppPNGDevice without writing a _1 file (using the MemoryStream)?

Comments

  • edited July 13
    Hi Jim,

    1. For the image device, each page of a report is exported with an underscore then page number as a suffix for the file name. If you are getting "_1" then you are not defining an initial file name (TppReport.TextFileName property). If you would like to give each file a unique name, you can use the TppImageDevice.OnAssignFileName event to do so.

    2. I am unsure how you are setting the DPI of the image. The TPNGImage class does not appear to contain a DPI property. This however is un-needed to increase the resolution of an image exported with ReportBuilder. Images viewed on screen at 100% are viewed in screen resolution. If you wish to create a higher resolution image, you will need to increase the size of the image using the TppImageDevice.Scale property. For instance, setting the scale property to 3, will give you a roughly 300dpi image (when printed to a 300dpi printer). This can be scaled down to fit on your screen, but when printed, all pixels will be present.



    Best Regards,

    Nico Cizik
    Digital Metaphors
    http://www.digital-metaphors.com
  • Hi Jim,
    Thanks for your quick reply.

    For clarification:
    We set the DPI via TppPNGDevice.scale := DPI value / 96. We set the DPI value because a label printer from our customer requires this . But if we set the DPI value and at the same time TppPNGDevice.outputStream := MemStream; the DPI value in the image is lost.
    If we do not set OutputStream, the DPI value remains correct, but we get the unwanted _1 file.

  • edited July 18
    Hi Jim,
    But if we set the DPI value and at the same time TppPNGDevice.outputStream := MemStream; the DPI value in the image is lost.
    I am unable to recreate this behavior here with a simple test. I tried in two ways. One using the Report.OnFileDeviceCreate event and the other by creating the TppPNGDevice myself. Both times the image exported to memory stream was of the correct scale. Below is my test code...
    //TEST 1

    procedure TForm1.FormCreate(Sender: TObject);
    begin
    FReportStream := TMemoryStream.Create;

    end;

    procedure TForm1.Button1Click(Sender: TObject);
    begin
    ppReport1.Print;

    FReportStream.SaveToFile('c:\TestScaleReport.png');

    end;

    procedure TForm1.ppReport1FileDeviceCreate(Sender: TObject);
    begin
    TppImageDevice(ppReport1.FileDevice).Scale := 2;
    ppReport1.FileDevice.OutputStream := FReportStream;

    end;

    procedure TForm1.FormDestroy(Sender: TObject);
    begin
    FReportStream.Free;

    end;

    //TEST 2

    procedure TForm1.Button2Click(Sender: TObject);
    var
    lPNGDevice: TppPNGDevice;
    lDeviceStream: TMemoryStream;
    begin

    lDeviceStream := TMemoryStream.Create;

    lPNGDevice := TppPNGDevice.Create(nil);

    try
    lPNGDevice.Scale := 2;
    lPNGDevice.OutputStream := lDeviceStream;

    lPNGDevice.Publisher := ppReport1.Publisher;

    ppReport1.PrintToDevices;

    lDeviceStream.SaveToFile('c:\TestScaleDevice.png');

    finally
    lPNGDevice.Free;
    lDeviceStream.Free;
    end;

    end;
    If we do not set OutputStream, the DPI value remains correct, but we get the unwanted _1 file.
    The solution to this is to give your image a file name and then implement the OnAssignFileName event of the image device. See #1 from my initial response.

    Best Regards,

    Nico Cizik
    Digital Metaphors
    http://www.digital-metaphors.com
  • Hello, Nico,
    Sorry for my late answer, but I was on vacation for a while. Can you try your example again with Scale = 2.08333333333 (200 / 96)? I tried that as you described, but the value seems to keep jumping back to the even value. Can you reproduce that?
  • Hi Jim,

    I tried the exact example above only changing the scale from 2 to 2.08333333333 and received the expected results.

    Exporting a report with a scale of 2 gave image dimensions of 1632 x 2112.

    Exporting a report with a scale of 2.08333333333 gave image dimensions of 1699 x 2199.

    If you would like to try my exact example, send a short email to support@digital-metaphors.com and I'll send it to you for testing.

    Best Regards,

    Nico Cizik
    Digital Metaphors
    http://www.digital-metaphors.com
Sign In or Register to comment.