Zapis plików bmp w jednym pdf

0

Dzień dobry,
mam w katalogu np 30-40 plików *.bmp. Chcę te pliki zapisać w jednym pdf'ie - każdy plik bmp to osobna strona. Wywołuję z poziomu programu wirtualną drukarkę pdf (Bullzip) i niby wszystko jest ok. Ale takie rozwiązanie wydaje mi się mało wygodne dla użytkownika. Czy jest jakaś możliwość, żeby zrobić to w 'locie' - użytkownik nie musi wskazywać plików bo program wie które pliki bmp ma zapisać do pdf i pod jaka nazwą.

Pozdrawiam

ratt

0

Dzięki grzegorz_so!
To chyba to, co jest mi potrzebne. Używałeś tego? Możesz podpowiedzieć jak się zabrac do rzeczy?

Pozdrawiam

ratt

0

tak używałem ale tyko do jednostronicowych wydruków tekstowych

  Pdf := TPdfDocumentGDI.Create;
  Page := lPdf.AddPage;
  Pdf.ScreenLogPixels := 85;
  pdf.canvas.Brush.Style := bsClear;
  /// tutaj utworzenie wydruku  analogicznie jak na drukarce
  ///  obiekt pdf ma property 'canvas'
  pdf.canvas.TextOut(xpos, ypos, tekst);

  Pdf.SaveToFile(File_Name)
0

Dzięki grzegorz_so,
poradziłem sobie z problemem i jeśli by ktoś miał podobny, to moja procedura działa. Wskazane biblioteki, wystarczy dołączyć do projektu. Poniżej proceura:

 procedure TForm1.BMP_PDFClick(Sender: TObject);
var
SciezkaDoKataloguBMP:string; //ścieżka do katalogu z plikami *.bmp
Obrazek:string; //nazwa ze ścieżką do pliku *.bmp
RR:TRect; //rozmiar obrazka
SearchResult : TSearchRec;
Bitmapa:TBitmap;
RR:rozmiar strony
begin
VLsciezkaDoPlikow:='';
VLsciezkaDoPlikow:='C:\PlikiBMP\';

with TGDIPages.Create(self) do
  try
    begin
    NewPageLayout(220,180,-1,-1);
          BeginDoc;
         if FindFirst(SciezkaDoKataloguBMP+'*.bmp', faAnyFile, SearchResult) = 0 then  //wyszukuje we wskazanym katalogu pliki *.bmp
          begin 
            repeat
              Obrazek:=SciezkaDoKataloguBMP+SearchResult.Name;
              Bitmapa := TBitmap.Create;
                    try
                       Bitmapa.LoadFromFile(Obrazek);
                       RR:=Rect(0,0,220,180);
                       DrawBMP(RR,Bitmapa);
                    finally
                       Bitmapa.Free;
                    end;
              NewPage;

              until FindNext(SearchResult) <> 0;
              FindClose(searchResult);
            end;
         EndDoc;
    end;
    ExportPDF('C:\PlikiPDF\nowyPlik.pdf',True,False)  //zapisuje we wskazanej lokalizacji plik *.pdf. Ostatnie 2 parametry: pokazuje błędy, otwiera plik po jego utworzeniu

  finally
    Free;
  end;

end;

Zamiast ExportPDF('C:\PlikiPDF\nowyPlik.pdf',True,False) można wstawić ShowPreviewForm; Wtedy widoczny jest podgląd pdf'a.

Pozdrawiam

ratt

0

ratt, dzięki za przykład , widzę że korzystasz z innej klasy z bibiloteki , pewnie lepiej odpowiadała Twoim potrzebom
pozdrawiam
grzgorz_so

1

@ratt - poprawiłem trochę Twój przykładowy kod:

procedure TForm1.BMPToPDFClick(Sender: TObject);
const
  BMP_SOURCE_PATH = 'C:\BMP Files\';
  BMP_FIND_MASK   = '*.bmp';
  PDF_DEST_NAME   = 'C:\PDF Files\NewFile.pdf';
const
  PAGE_LAYOUT_RECT: TRect = (Left: 220; Top: 180; Right: -1; Bottom: -1);
  BMP_TARGET_RECT:  TRect = (Left: 0; Top: 0; Right: 220; Bottom: 180);
var
  srBitmap: TSearchResult;
  bmpFound: TBitmap;
begin
  with TGDIPages.Create(Self) do
  try
    NewPageLayout(220, 180, -1, -1);
    BeginDoc();
    try
      if FindFirst(BMP_SOURCE_PATH + BMP_FIND_MASK, faAnyFile, srBitmap) = 0 then
      try
        bmpFound := TBitmap.Create();
        try
          repeat
            bmpFound.LoadFromFile(BMP_SOURCE_PATH + srBitmap.Name);
            DrawBMP(BMP_TARGET_RECT, bmpFound);
          until FindNext(srBitmap) <> 0;
        finally
          bmpFound.Free();
        end;
      finally
        FindClose(srBitmap);
      end;
    finally
      EndDoc();
    end;

    ExportPDF(PDF_DEST_NAME, True, False);
  finally
    Free();
  end;
end;

Trochę zabezpieczeń, wykluczenie tworzenia obiektu bitmapy tyle razy, ile plików zostanie znalezionych (to zbędne, bo metoda LoadFromFile kasuje wcześniejszą zawartość, o ile jakaś istniała); Powinno działać, choć nie testowałem; W każdym razie w przyszłości staraj się lepiej formatować kod i unikać zbędnych operacji, jednocześnie zabezpieczając poprawne zwolnienie z paimęci wszystkich obiektów.

0

Dzięki furious programming,
mam jeszcze jeden problem. Zapisuję na dysku pliki, których nazwy to liczby od 1 do n, nadawane przy ich zapisie. Chcę pobierać ich nazwy w kolejności zapisu czyli 1,2,3,4 ...n. Niestety dla programu kolejnośc jest 1,10,100,2,20,200 itd. Czy jednym rozwiązaniem jest użycie tablicy dynamicznej i pobieranie nazw w kolejności indeksów?

Pozdrawiam

ratt

2

jeśli znasz zakres nazw (liczb od 1 do n) to możesz w pętli od 1 do n sprawdzać czy taki plik istnieje i odczytywać jego treść.
Jeśli nie znasz zakresu to czytasz nazwy kolejnych plików do datasetu (Tcliendataset) z dwoma polami , nazwa_pliku (string) oraz waga (int) i indeksujesz dataset po polu 'waga'
, pole 'waga' wypełniasz jako inttostr(nazwa_pliku)
a na koniec odczytujesz treść plików "przelatując" poindeksowany dataset od pierwszej do ostatniej pozycji
Taką operację pewnie można by też zrobić na jakiejś indeksowanej liście

0

Dzięki,
ale nie wiem ile będzie tych plików. Robię to jednak inaczej. Zapisując pliki na dysku równolegle zapisuję ich nazwy do pliku *.txt, kolejność zachowana. Potem pobieram rekordy pliku i mam to, czego potrzebuję. Może to trochę prymitywne ale działa.

Pozdrawiam

ratt

1

@ratt - jeśli nie znasz ilości utworzonych przez Twój program plików, to zawsze możesz użyć funkcji FileExists do sprawdzenia, czy plik faktycznie istnieje i jeśli tak - otworzyć go; Kod mógłby wyglądać mniej więcej w ten sposób:

var
  tfInput: TextFile;
  intFileIdx: Integer;

{..}

intFileIdx := 1;

while FileExists(Format('%d.txt', [intFileIdx])) do
begin
  AssignFile(tfInput, Format('%d.txt', [intFileIdx]));
  Reset(tfInput);
  try
    // obróbka danych pliku
  finally
    CloseFile(tfInput);
  end;

  Inc(intFileIdx);
end;

Pętla będzie działać dotąd, aż funkcja FileExists zwróci False, czyli plik o podanej nazwie nie istnieje na dysku; Wtedy nie będziesz musiał znać ilości plików.

1 użytkowników online, w tym zalogowanych: 0, gości: 1