View Issue Details

IDProjectCategoryView StatusLast Update
0023326LazarusLazReportpublic2012-11-19 16:33
ReporterLuiz AmericoAssigned ToJesus Reyes 
PrioritynormalSeverityminorReproducibilityalways
Status closedResolutionfixed 
Product VersionProduct Build 
Target Version1.2.0Fixed in Version1.1 (SVN) 
Summary0023326: Image is cropped when exported to pdf in LazReport
DescriptionIf a image in report has stretch = false, it will be cropped when exported to pdf

Follows example app.

This occurs because the pdf filter scales down the width and height of the image, e.g., an image with width of 200, will be assigned a width of 160. When PRImage.Stretch is true no problem, the pdf will show entire image, otherwise will show only part of the image.

TagsNo tags attached.
Fixed in Revision39284
LazTarget1.2
Widgetset
Attached Files
  • LazReportPdfImage.zip (3,667 bytes)
  • lazreport_pdfimagesize.diff (2,495 bytes)
    Index: lazreport/source/addons/pdfexport/lr_e_pdf.pas
    ===================================================================
    --- lazreport/source/addons/pdfexport/lr_e_pdf.pas	(revision 39275)
    +++ lazreport/source/addons/pdfexport/lr_e_pdf.pas	(working copy)
    @@ -48,6 +48,7 @@
             FOutline: TPROutLineEntry;
             FPageNo : Integer;
             DummyControl: TForm;
    +        procedure GetScaledImageSize(Sender: TObject; var AWidth, AHeight: Integer);
             procedure AddShape(Data: TShapeData; x, y, h, w: integer);
             procedure DefaultShowView(View: TfrView; nx, ny, ndy, ndx: Integer);
         public
    @@ -79,6 +80,12 @@
         PDFEscx = 0.792553191;
         PDFEscy = 0.785447761;
     
    +procedure TfrTNPDFExportFilter.GetScaledImageSize(Sender: TObject; var AWidth, AHeight: Integer);
    +begin
    +  AWidth := trunc((AWidth) * PDFEscx + 1.5);
    +  AHeight := trunc((AHeight) * PDFEscy + 1.5);
    +end;
    +
     procedure TfrTNPDFExportFilter.AddShape(Data: TShapeData; x, y, h, w: integer);
     
       function CreateShape(ShapeClass: TPRShapeClass): TPRShape;
    @@ -304,14 +311,17 @@
       r: Double;
       L: Integer;
       pw, ph: Integer;
    +  Picture: TPicture;
     begin
    +  Picture := View.Picture;
     
    -  if View.Picture.Graphic is TJpegImage then
    +  if Picture.Graphic is TJpegImage then
         PRImage := TPRJpegImage.Create(PRPanel)
       else
         PRImage := TPRImage.Create(PRPanel);
     
       PRImage.Parent := PRPanel;
    +  PRImage.OnGetImageSize := @GetScaledImageSize;
     
       ph := h;
       pw := w;
    @@ -319,9 +329,9 @@
       if view.Stretched then
       begin
         if (View.Flags and flPictRatio<>0) and
    -       (View.Picture.Width>0) and (View.Picture.Height>0) then
    +       (Picture.Width>0) and (Picture.Height>0) then
         begin
    -      r  := View.Picture.Width/View.Picture.Height;
    +      r  := Picture.Width/Picture.Height;
           if (w/h) < r then
           begin
             L := h;
    @@ -340,8 +350,8 @@
       end
       else
       if (View.Flags and flPictCenter<>0) then begin
    -    pw := trunc(View.Picture.Width * PDFEscX + 1.5);
    -    ph := trunc(View.Picture.Height * PDFEscY + 1.5);
    +    pw := trunc(Picture.Width * PDFEscX + 1.5);
    +    ph := trunc(Picture.Height * PDFEscY + 1.5);
          x := x + (w - pw) div 2 - 1;
          y := y + (h - ph) div 2 - 1;
       end;
    @@ -355,7 +365,7 @@
       PRImage.Height := ph;
       PRImage.Width := pw;
     
    -  PRImage.Picture.Graphic := View.Picture.Graphic;
    +  PRImage.Picture.Graphic := Picture.Graphic;
     end;
     
     procedure TfrTNPDFExportFilter.ShowRoundRect(View: TfrRoundRectView; x, y, h,
    
  • powerpdf_imagesize.diff (2,492 bytes)
    Index: PReport.pas
    ===================================================================
    --- PReport.pas	(revision 2593)
    +++ PReport.pas	(working copy)
    @@ -100,6 +100,8 @@
       TPRPrintItemEvent = TPRPrintPanelEvent;
       TPRPrintChildPanelEvent = procedure(Sender: TObject; ACanvas: TPRCanvas;
                                   ACol, ARow: integer; Rect: TRect) of object;
    +  TPRGetImageSize = procedure(Sender: TObject;
    +                              var AWidth, AHeight: Integer) of object;
       TPrintDirection = (pdHorz, pdVert);
       TPRDestinationType = TPdfDestinationType;
       TPRPageLayout = TPdfPageLayout;
    @@ -485,6 +487,7 @@
       { TPRImage }
       TPRImage = class(TPRItem)
       private
    +    FOnGetImageSize: TPRGetImageSize;
         FSharedName: string;
         procedure SetStretch(Value: boolean);
         procedure SetProportional(AValue: boolean);
    @@ -497,11 +500,13 @@
         procedure Paint; override;
         procedure Print(ACanvas: TPRCanvas; ARect: TRect); override;
         procedure CalcProportionalBounds(var AWidth, AHeight: Integer);
    +    procedure DoGetImageSize(var AWidth, AHeight: Integer);
       public
         constructor Create(AOwner: TComponent); override;
         destructor Destroy; override;
         property SharedName: string read FSharedName write FSharedName;
       published
    +    property OnGetImageSize: TPRGetImageSize read FOnGetImageSize write FOnGetImageSize;
         property Picture: TPicture read FPicture write SetPicture;
         property SharedImage: boolean read FSharedImage write FSharedImage;
         property Stretch: boolean read FStretch write SetStretch default true;
    @@ -2481,9 +2486,14 @@
           DrawXObject(Left, GetPage.Height - Top - AHeight, AWidth, AHeight, FXObjectName)
         end
         else
    -      DrawXObjectEx(Left, GetPage.Height - Top - FPicture.Height,
    -            FPicture.Width, FPicture.Height,
    +    begin
    +      AWidth := FPicture.Width;
    +      AHeight := FPicture.Height;
    +      DoGetImageSize(AWidth, AHeight);
    +      DrawXObjectEx(Left, GetPage.Height - Top - AHeight,
    +            AWidth, AHeight,
                 Left, GetPage.Height - Top - Height, Width, Height, FXObjectName);
    +    end;
     end;
     
     procedure TPRImage.CalcProportionalBounds(var AWidth, AHeight: Integer);
    @@ -2500,6 +2510,12 @@
       end;
     end;
     
    +procedure TPRImage.DoGetImageSize(var AWidth, AHeight: Integer);
    +begin
    +  if Assigned(FOnGetImageSize) then
    +    FOnGetImageSize(Self, AWidth, AHeight);
    +end;
    +
     // Create
     constructor TPRImage.Create(AOwner: TComponent);
     begin
    
    powerpdf_imagesize.diff (2,492 bytes)

Activities

2012-11-15 03:14

 

LazReportPdfImage.zip (3,667 bytes)

Luiz Americo

2012-11-15 12:46

developer   ~0063844

The problem is that powerpdf is creating a image with the full image size (200x80) and clipping using the scaled down size (160/64) set by the filter

Attached two patches to fix the issue.

One for powerpdf (in lazarus-ccr)
Other for lazreport filter

It add a event to get the image size, so the filter can return the scaled size.

2012-11-15 12:46

 

lazreport_pdfimagesize.diff (2,495 bytes)
Index: lazreport/source/addons/pdfexport/lr_e_pdf.pas
===================================================================
--- lazreport/source/addons/pdfexport/lr_e_pdf.pas	(revision 39275)
+++ lazreport/source/addons/pdfexport/lr_e_pdf.pas	(working copy)
@@ -48,6 +48,7 @@
         FOutline: TPROutLineEntry;
         FPageNo : Integer;
         DummyControl: TForm;
+        procedure GetScaledImageSize(Sender: TObject; var AWidth, AHeight: Integer);
         procedure AddShape(Data: TShapeData; x, y, h, w: integer);
         procedure DefaultShowView(View: TfrView; nx, ny, ndy, ndx: Integer);
     public
@@ -79,6 +80,12 @@
     PDFEscx = 0.792553191;
     PDFEscy = 0.785447761;
 
+procedure TfrTNPDFExportFilter.GetScaledImageSize(Sender: TObject; var AWidth, AHeight: Integer);
+begin
+  AWidth := trunc((AWidth) * PDFEscx + 1.5);
+  AHeight := trunc((AHeight) * PDFEscy + 1.5);
+end;
+
 procedure TfrTNPDFExportFilter.AddShape(Data: TShapeData; x, y, h, w: integer);
 
   function CreateShape(ShapeClass: TPRShapeClass): TPRShape;
@@ -304,14 +311,17 @@
   r: Double;
   L: Integer;
   pw, ph: Integer;
+  Picture: TPicture;
 begin
+  Picture := View.Picture;
 
-  if View.Picture.Graphic is TJpegImage then
+  if Picture.Graphic is TJpegImage then
     PRImage := TPRJpegImage.Create(PRPanel)
   else
     PRImage := TPRImage.Create(PRPanel);
 
   PRImage.Parent := PRPanel;
+  PRImage.OnGetImageSize := @GetScaledImageSize;
 
   ph := h;
   pw := w;
@@ -319,9 +329,9 @@
   if view.Stretched then
   begin
     if (View.Flags and flPictRatio<>0) and
-       (View.Picture.Width>0) and (View.Picture.Height>0) then
+       (Picture.Width>0) and (Picture.Height>0) then
     begin
-      r  := View.Picture.Width/View.Picture.Height;
+      r  := Picture.Width/Picture.Height;
       if (w/h) < r then
       begin
         L := h;
@@ -340,8 +350,8 @@
   end
   else
   if (View.Flags and flPictCenter<>0) then begin
-    pw := trunc(View.Picture.Width * PDFEscX + 1.5);
-    ph := trunc(View.Picture.Height * PDFEscY + 1.5);
+    pw := trunc(Picture.Width * PDFEscX + 1.5);
+    ph := trunc(Picture.Height * PDFEscY + 1.5);
      x := x + (w - pw) div 2 - 1;
      y := y + (h - ph) div 2 - 1;
   end;
@@ -355,7 +365,7 @@
   PRImage.Height := ph;
   PRImage.Width := pw;
 
-  PRImage.Picture.Graphic := View.Picture.Graphic;
+  PRImage.Picture.Graphic := Picture.Graphic;
 end;
 
 procedure TfrTNPDFExportFilter.ShowRoundRect(View: TfrRoundRectView; x, y, h,

2012-11-15 12:46

 

powerpdf_imagesize.diff (2,492 bytes)
Index: PReport.pas
===================================================================
--- PReport.pas	(revision 2593)
+++ PReport.pas	(working copy)
@@ -100,6 +100,8 @@
   TPRPrintItemEvent = TPRPrintPanelEvent;
   TPRPrintChildPanelEvent = procedure(Sender: TObject; ACanvas: TPRCanvas;
                               ACol, ARow: integer; Rect: TRect) of object;
+  TPRGetImageSize = procedure(Sender: TObject;
+                              var AWidth, AHeight: Integer) of object;
   TPrintDirection = (pdHorz, pdVert);
   TPRDestinationType = TPdfDestinationType;
   TPRPageLayout = TPdfPageLayout;
@@ -485,6 +487,7 @@
   { TPRImage }
   TPRImage = class(TPRItem)
   private
+    FOnGetImageSize: TPRGetImageSize;
     FSharedName: string;
     procedure SetStretch(Value: boolean);
     procedure SetProportional(AValue: boolean);
@@ -497,11 +500,13 @@
     procedure Paint; override;
     procedure Print(ACanvas: TPRCanvas; ARect: TRect); override;
     procedure CalcProportionalBounds(var AWidth, AHeight: Integer);
+    procedure DoGetImageSize(var AWidth, AHeight: Integer);
   public
     constructor Create(AOwner: TComponent); override;
     destructor Destroy; override;
     property SharedName: string read FSharedName write FSharedName;
   published
+    property OnGetImageSize: TPRGetImageSize read FOnGetImageSize write FOnGetImageSize;
     property Picture: TPicture read FPicture write SetPicture;
     property SharedImage: boolean read FSharedImage write FSharedImage;
     property Stretch: boolean read FStretch write SetStretch default true;
@@ -2481,9 +2486,14 @@
       DrawXObject(Left, GetPage.Height - Top - AHeight, AWidth, AHeight, FXObjectName)
     end
     else
-      DrawXObjectEx(Left, GetPage.Height - Top - FPicture.Height,
-            FPicture.Width, FPicture.Height,
+    begin
+      AWidth := FPicture.Width;
+      AHeight := FPicture.Height;
+      DoGetImageSize(AWidth, AHeight);
+      DrawXObjectEx(Left, GetPage.Height - Top - AHeight,
+            AWidth, AHeight,
             Left, GetPage.Height - Top - Height, Width, Height, FXObjectName);
+    end;
 end;
 
 procedure TPRImage.CalcProportionalBounds(var AWidth, AHeight: Integer);
@@ -2500,6 +2510,12 @@
   end;
 end;
 
+procedure TPRImage.DoGetImageSize(var AWidth, AHeight: Integer);
+begin
+  if Assigned(FOnGetImageSize) then
+    FOnGetImageSize(Self, AWidth, AHeight);
+end;
+
 // Create
 constructor TPRImage.Create(AOwner: TComponent);
 begin
powerpdf_imagesize.diff (2,492 bytes)

Jesus Reyes

2012-11-15 22:38

developer   ~0063854

Thanks for you patches Luiz, seems we fixed the same at the same time, I have added a couple of properties to TPRImage so it can be scaled differently than what is used internally in PowerPDF, noticed your patch too late, sorry.

Please test, if it doesn't work fine for you, I will apply your patches instead.

Luiz Americo

2012-11-19 16:33

developer   ~0063923

Thanks. This fixes the issue

Issue History

Date Modified Username Field Change
2012-11-15 03:14 Luiz Americo New Issue
2012-11-15 03:14 Luiz Americo File Added: LazReportPdfImage.zip
2012-11-15 03:14 Luiz Americo LazTarget => -
2012-11-15 12:46 Luiz Americo Note Added: 0063844
2012-11-15 12:46 Luiz Americo File Added: lazreport_pdfimagesize.diff
2012-11-15 12:46 Luiz Americo File Added: powerpdf_imagesize.diff
2012-11-15 22:31 Jesus Reyes Status new => assigned
2012-11-15 22:31 Jesus Reyes Assigned To => Jesus Reyes
2012-11-15 22:38 Jesus Reyes Fixed in Revision => 39284
2012-11-15 22:38 Jesus Reyes LazTarget - => 1.2
2012-11-15 22:38 Jesus Reyes Status assigned => resolved
2012-11-15 22:38 Jesus Reyes Fixed in Version => 1.1 (SVN)
2012-11-15 22:38 Jesus Reyes Resolution open => fixed
2012-11-15 22:38 Jesus Reyes Note Added: 0063854
2012-11-15 22:38 Jesus Reyes Target Version => 1.2.0
2012-11-19 16:33 Luiz Americo Status resolved => closed
2012-11-19 16:33 Luiz Americo Note Added: 0063923