Dodanie obrazu JPG do PDF - problem z dopasowaniem obrazka do strony dokumentu

Dodanie obrazu JPG do PDF - problem z dopasowaniem obrazka do strony dokumentu
U3
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 196
0

Witam,

mam plik na dysku zapisany w formie graficznej .jpg, chciałbym dodać ten plik do pliku PDF najlepiej aby strona w PDF dopasowała się do rozmiaru/rozdzielczości obrazka.

Widziałem jakiś czas temu w necie przykład:

Kopiuj
procedure TForm1.SpeedButton5Click(Sender: TObject);
var
pdfDoc:TPdfDocument;
pdfpage:TPdfpage;
JpegImage:TJpegImage;
pdfImage:TPdfImage;
begin
pdfDoc := TPdfDocument.Create;
pdfpage := pdfDoc.AddPage;
JpegImage := TJpegImage.Create;
JpegImage.LoadFromFile('C:\SorgentiDelphi\Twain2\immagini\pag_1.jpg');
//JpegImage.ForceJPEGCompression:=90;
pdfImage := TPdfImage.Create(pdfDoc, jpegimage,true);
//pdfImage:= TPdfImage.CreateJpegDirect(pdfDoc,'C:\SorgentiDelphi\Twain2\immagini\pag_1.jpg');
//pdfImage := TPdfImage.Create(pdfDoc, jpegimage);
pdfDoc.AddXObject('image1', pdfimage);
//pdfDoc.Canvas.DrawXObject(0,0,120,230, 'image1');

  pdfDoc.Canvas.DrawXObject(0, pdfpage.PageHeight-900,600, 900, 'image1');
//pdfDoc.Canvas.DrawXObject(0, pdfpage.PageHeight-JpegImage.Height,JpegImage.Width, JpegImage.Height, 'image1');
pdfDoc.SaveToFile('test2.pdf');
pdfDoc.Free;

Niestety nie działa on w w Delphi 2007.

Przekombinowałem to w coś takiego:

Kopiuj
procedure Tfrmdm.jpgToPdf(PicturePath: string);
var
  pdfDoc: TPdfDocument;
  pdfpage: TPdfpage;
  JpegImage: TJpegImage;
  pdfImage: TPdfImage;
begin
  pdfDoc := TPdfDocument.Create(nil);
  pdfDoc.FileName := ExtractFileDir(Application.ExeName) + '\abc.pdf' ;
  pdfDoc.BeginDoc;
  JpegImage := TJpegImage.Create;
  JpegImage.LoadFromFile(PicturePath);
  pdfImage := TPdfImage.Create(jpegimage, itcJpeg,pdfDoc);

  JpegImage.SetSize(pdfDoc.PageWidth, pdfDoc.PageHeight); // tu się wywala

  pdfDoc.AddImage(jpegimage, itcJpeg);
  pdfDoc.Canvas.Draw(0, 0,jpegimage);
  pdfDoc.EndDoc;
  pdfDoc.Free;
end;

Problem jest taki, że obrazek wychodzi poza obszar strony, a gdy próbuję zmienić rozmiar obrazka to dostaję komunikat, że nie mogę zmienić rozmiaru JPG. No ok, ale jak mam dopasować obrazek do strony i wycentrować go?

flowCRANE
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Tuchów
  • Postów: 12272
0

Skoro chcesz dopasować stronę w PDF do obrazka, to dlaczego zmieniasz rozmiar obrazka, a nie strony? Poza tym dodaj do kodu bloki Try Finally i ewentualnie Try Except żeby uchronić program przed wyciekami pamięci;

// tu się wywala

Co to znaczy "się wywala"? Generuje wyjątek, czy działa wbrew Twoim oczekiwaniom?

Problem jest taki, że obrazek wychodzi poza obszar strony, a gdy próbuję zmienić rozmiar obrazka to dostaję komunikat, że nie mogę zmienić rozmiaru JPG.

Podaj treść tego komunikatu, oraz poszukaj w Google - być może (a raczej na pewno) ktoś już miał podobny lub taki sam problem i otrzymał odpowiedź z rozwiązaniem.


Niestety mam tylko stare Delphi7 i nie mam jak sprawdzić, bo klasa TJPEGImage nie posiada metody SetSize.

U3
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 196
0

Dzięki Furious za wskazówki. Poradziłem sobie :)

U3
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 196
1

Podzielę się, podzielę :)

Więc...

Kopiuj
//Procedurka konwertuje jpg na pdf
procedure Tfrmdm.jpgToPdf(PicturePath: string);
var
  pdfDoc: TPdfDocument;
  JpegImage: TJpegImage;
  pdfImage: TPdfImage;
begin
  pdfDoc := TPdfDocument.Create(nil);
  pdfDoc.FileName := ExtractFilePath(Application.ExeName)+'Dokumenty\' + ExtractFileName(PicturePath) + '.pdf'; // ścieżka gdzie ma powstać plik PDF
  pdfDoc.BeginDoc; // stwórz pusty dokument

  // funkcja sprawdza rozmiar obrazka ze stroną A4
  // jeżeli szerokość obrazka jest większa niż wysokość strony to znaczy, że mamy stronę poziomą
  if GetPicSize('Width', ExtractFilePath(Application.ExeName)+'Dokumenty\' + ExtractFileName(PicturePath) + '.jpeg') > GetPicSize('Height', ExtractFilePath(Application.ExeName)+'Dokumenty\' + ExtractFileName(PicturePath) + '.jpeg') then
    pdfDoc.Page[0].Orientation := poPageLandScape;

  // 
  ResizeImage(ExtractFilePath(Application.ExeName)+'Dokumenty\' + ExtractFileName(PicturePath) + '.jpeg', pdfDoc.PageWidth);

  JpegImage := TJpegImage.Create;
  JpegImage.LoadFromFile(ExtractFilePath(Application.ExeName)+'Dokumenty\' +  ExtractFileName(PicturePath) + '.jpeg');
  pdfImage := TPdfImage.Create(jpegimage, itcJpeg,pdfDoc);

  pdfDoc.AddImage(jpegimage, itcJpeg);
  pdfDoc.Canvas.Draw(0, 0,jpegimage);
  pdfDoc.EndDoc;
  pdfDoc.Free;
end;

// pobierz rozmiar obrazka jpg

Kopiuj
function GetPicSize(Size, FilePath: string): integer;
var
  Bitmap: TBitmap;
  JPEGImage: TJPEGImage;
begin
  Result := 0;
  if (FilePath = '') then    // No FileName so nothing
    Result := 0  //to load - return False...
  else
  begin
    try  // Start of try except
      JPEGImage := TJPEGImage.Create;  // Create the JPEG image... try  // now
      Bitmap := TBitmap.Create;
      try  // to load the file but
        JPEGImage.LoadFromFile(FilePath);
        // might fail...with an Exception.
        Bitmap.Assign(JPEGImage);
        if Size = 'Width' then
          Result := Bitmap.Width
        else
          Result := Bitmap.Height;
        // Assign the image to our bitmap.Result := True;
        // Got it so return True.
      finally
        JPEGImage.Free;  // ...must get rid of the JPEG image. finally
        Bitmap.Free;
      end; {try}
    except
      Result := 0; // never Loaded, so return False.
    end; {try}
  end; {if}
end;
Kopiuj
// aby zmienić rozmiar JPG najpierw należy zamienić go na bitmapę
function ResizeImage(FileName: string; MaxWidth: Integer): Boolean;
var
  OldBitmap: TBitmap;
  NewBitmap: TBitmap;
  aWidth: Integer;
begin
  Result := False;
  OldBitmap := TBitmap.Create;
  try
    if LoadJPEGPictureFile(OldBitmap, ExtractFilePath(FileName),
      ExtractFileName(FileName)) then
    begin
      aWidth := OldBitmap.Width;
      if (OldBitmap.Width > MaxWidth) then
      begin
        aWidth    := MaxWidth;
        NewBitmap := TBitmap.Create;
        try
          NewBitmap.Width  := MaxWidth;
          NewBitmap.Height := MulDiv(MaxWidth, OldBitmap.Height, OldBitmap.Width);
          SmoothResize(OldBitmap, NewBitmap);
          RenameFile(FileName, ChangeFileExt(FileName, '.$$$'));
          if SaveJPEGPictureFile(NewBitmap, ExtractFilePath(FileName),
            ExtractFileName(FileName), 100) then
            DeleteFile(ChangeFileExt(FileName, '.$$$'))
          else
            RenameFile(ChangeFileExt(FileName, '.$$$'), FileName);
        finally
          NewBitmap.Free;
        end; {try}
        Result := True;
      end; {if}
    end; {if}
  finally
    OldBitmap.Free;
  end; {try}
end;
Kopiuj
// funkcja odpowiada przy konwersji za uzupełnienie pixeli obrazka na takie, 
// które najbardziej pasują do sąsiadujących
procedure SmoothResize(Src, Dst: TBitmap);
var
  x, y: Integer;
  xP, yP: Integer;
  xP2, yP2: Integer;
  SrcLine1, SrcLine2: pRGBArray;
  t3: Integer;
  z, z2, iz2: Integer;
  DstLine: pRGBArray;
  DstGap: Integer;
  w1, w2, w3, w4: Integer;
begin
  Src.PixelFormat := pf24Bit;
  Dst.PixelFormat := pf24Bit;

  if (Src.Width = Dst.Width) and (Src.Height = Dst.Height) then
    Dst.Assign(Src)
  else
  begin
    DstLine := Dst.ScanLine[0];
    DstGap  := Integer(Dst.ScanLine[1]) - Integer(DstLine);

    xP2 := MulDiv(pred(Src.Width), $10000, Dst.Width);
    yP2 := MulDiv(pred(Src.Height), $10000, Dst.Height);
    yP  := 0;

    for y := 0 to pred(Dst.Height) do
    begin
      xP := 0;

      SrcLine1 := Src.ScanLine[yP shr 16];

      if (yP shr 16 < pred(Src.Height)) then
        SrcLine2 := Src.ScanLine[succ(yP shr 16)]
      else
        SrcLine2 := Src.ScanLine[yP shr 16];

      z2  := succ(yP and $FFFF);
      iz2 := succ((not yp) and $FFFF);
      for x := 0 to pred(Dst.Width) do
      begin
        t3 := xP shr 16;
        z  := xP and $FFFF;
        w2 := MulDiv(z, iz2, $10000);
        w1 := iz2 - w2;
        w4 := MulDiv(z, z2, $10000);
        w3 := z2 - w4;
        DstLine[x].rgbtRed := (SrcLine1[t3].rgbtRed * w1 +
          SrcLine1[t3 + 1].rgbtRed * w2 +
          SrcLine2[t3].rgbtRed * w3 + SrcLine2[t3 + 1].rgbtRed * w4) shr 16;
        DstLine[x].rgbtGreen :=
          (SrcLine1[t3].rgbtGreen * w1 + SrcLine1[t3 + 1].rgbtGreen * w2 +

          SrcLine2[t3].rgbtGreen * w3 + SrcLine2[t3 + 1].rgbtGreen * w4) shr 16;
        DstLine[x].rgbtBlue := (SrcLine1[t3].rgbtBlue * w1 +
          SrcLine1[t3 + 1].rgbtBlue * w2 +
          SrcLine2[t3].rgbtBlue * w3 +
          SrcLine2[t3 + 1].rgbtBlue * w4) shr 16;
        Inc(xP, xP2);
      end; {for}
      Inc(yP, yP2);
      DstLine := pRGBArray(Integer(DstLine) + DstGap);
    end; {for}
  end; {if}
end; {SmoothResize}

Może komuś się przyda.

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.