Program losowo nie drukuje na płótnie drukarki

0

Witam,
Program nanosi kilka obrazów na płótno drukarki. Obrazy są pobierane z dysku i obrabiane w programie. Niestety często jeden lub kilka nie było drukowanych, więc zacząłem szukać przyczyny. Oto "odchudzona" procedura która nanosi obrazy na płótno:

procedure TForm1.Kartka;
var R:TRect;
begin
   Obraz(typ);
   R:=Rect(500,1000,7000,4000);
   printer.Canvas.StretchDraw(R,obr);
   Obr.SaveToFile('1.bmp');
   R:=Rect(500,5000,7000,8000);
   printer.Canvas.StretchDraw(R,obr);
   Obr.SaveToFile('2.bmp');
   R:=Rect(500,9000,7000,12000);
   printer.Canvas.StretchDraw(R,obr);
   Obr.SaveToFile('3.bmp');
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
   obr.Free;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
   {...}
   obr:=TBitmap.Create;
   {...}
end;

procedure TForm1.Obraz(typ:string[20]);
begin
   {...}
   //if FileExists(sciezka+typ+'.bmp') then
   obr.LoadFromFile(sciezka+typ+'.bmp');
   {...}
end;

Usuwałem z kodu zmienne odpowiadające za położenie i wielkość obrazów, lecz to nie pomagało. Zacząłem zapisywać do plików obrobione obrazy i wszystkie obrazy pojawiają się na dysku, lecz pomimo to na wydruku ich czasem nie ma. Każdy z obrazów zajmuje 15 do 20 MB. Czasem nie ma jednego lub dwóch z nich, chociaż najczęściej są wszystkie.
Procedura "Obraz" działa poprawnie, obrobione obrazy są poprawnie (testowo) zapisywane na dysku jako "1.bmp","2.bmp" i "3.bmp".
Czym to może być spowodowane? Za duże obrazy, brak pamięci?
Problem ten występuje przy drukowaniu na różnych typach kopiarek (Canon i Minolta) w PCL i w PS oraz przy tworzeniu PDF, nie występuje natomiast przy drukowaniu do pliku XPS.
Pozdrawiam.

0

Nie jestem specem od drukowania ale wygląda na to, że jest to brak pamięci podręcznej, spróbuj np. po załadowaniu obrazu nr 1 wydrukowaniu zwolnić pamięć, następnie załadować, wydrukować obraz nr 2 i zwolnić pamięć następnie obraz nr 3 : załadować, wydrukować i zwolnić pamięć itp...

0

Dziękuję za podpowiedź.
Próbowałem obr.FreeImage i obr.ReleaseHandle lecz nie pomogło.

Jeśli ma to jakieś znaczenie, to zaobserwowałem, że jeśli drukuję jedną kartkę, to braki występują zawsze, jeśli jest około 10 kartek wydruku, to braki są zawsze na pierwszej i czasami jeden brak około 5-tej karki, powyżej 10-tej kartki nie wystąpiły chyba nigdy.

0

Nie czuję się specjalistą w tej dziedzinie, ale czy pomiędzy kolejnymi procedurami jest zastosowany jakiś mechanizm opóźniania? Może jakaś procedura kończy się wcześniej niż powinna ( stąd losowość o której mówisz )?

0

może to być też problem z buforowaniem obrazu do drukarki, przy pierwszych stronach nie zdążą się obrazy zbuforować bo są nieco duże, przy kolejnych "bufor" już nadąża....

0

Jeśli chcecie wiedzieć czy faktycznie problemem jest buforowanie po stronie urządzenia drukującego to nic nie stoi na przeszkodzie, aby w innym programie przygotować tak duże obrazki i wysłać je do wydruku.

0

Witam,
Nie jest to problem urządzenia, wcześniej drukowałem z Photoshopa, i nie było takich błędów. Używany przeze mnie sprzęt też do tanich nie należy.
W pętli drukowania też nie ma żadnych procedur, które mogłyby się za wcześnie skończyć. Dla pewności przed i po poleceniu printer.Canvas.StretchDraw(R,obr) dawałem opóźnienie, lecz nawet 10 sekund nie pomagało.
Przed chwilą dodałem printer.Canvas.FillRect(R) przed każdym printer.Canvas.StretchDraw(R,obr) i to poskutkowało, jak na razie nie ma błędów.

0
Klakierus napisał(a):

Przed chwilą dodałem printer.Canvas.FillRect(R) przed każdym printer.Canvas.StretchDraw(R,obr) i to poskutkowało, jak na razie nie ma błędów.

No dobrze, ale jak to ma się do tego, o czym pisałeś wcześniej?

Klakierus napisał(a):

Niestety często jeden lub kilka nie było drukowanych, więc zacząłem szukać przyczyny.

Wcześniej była mowa o gubieniu obrazków, a to rozwiązanie które podałeś, jedynie czyści płótno.

To by rozwiązywało problem, gdybyś najpierw namalował i puścił do wydruku duży obraz, następnie nie wyczyścił płótna (pomocniczego obrazu) i chciał wydrukować mniejszy obraz – wtedy ten większy by wystawał ze spodu i psuł robotę. A z tego co widzę, problem jest zupełnie inny.

Ktoś może to wyjaśnić? Ciekaw jestem dlaczego tak się dzieje.

0
furious programming napisał(a):

No dobrze, ale jak to ma się do tego, o czym pisałeś wcześniej?

Szukałem rozwiązania, najpierw dawałem opóźnienia. Potem próbowałem zapchać bufor, zaśmiecić płótno drukarki i je wyczyścić, to pomogło. Samo printer.Canvas.FillRect(R) wystarczyło.

0

Odświeżam temat,
Czy ktoś może mi wyjaśnić dlaczego używając przykładowego kodu

procedure TForm1.Drukuj;
var R:TRect;
begin
   Obraz(typ);
   R:=Rect(500,1000,7000,4000);
   printer.Canvas.StretchDraw(R,obr);
   R:=Rect(500,5000,7000,8000);
   printer.Canvas.StretchDraw(R,obr);
   R:=Rect(500,9000,7000,12000);
   printer.Canvas.StretchDraw(R,obr);
end;

otrzymuję w losowych miejscach na losowych wydrukach braki, a po modyfikacji (logicznie biorąc bezsensownej) nie ma żadnych błędów?

procedure TForm1.Drukuj;
var R:TRect;
begin
   Obraz(typ);
   R:=Rect(500,1000,7000,4000);
   printer.Canvas.FillRect(R);
   printer.Canvas.StretchDraw(R,obr);
   R:=Rect(500,5000,7000,8000);
   printer.Canvas.FillRect(R);
   printer.Canvas.StretchDraw(R,obr);
   R:=Rect(500,9000,7000,12000);
   printer.Canvas.FillRect(R);
   printer.Canvas.StretchDraw(R,obr);
end;

Zawsze braki były (i są jeśli usunę FillRect) na pierwszej stronie, zawsze brakowało drugiego lub trzeciego obrazka. Jeśli drukowałem 10, 20 czy 100 stron, to braków było coraz mniej, jednak stale się pojawiały co kilka stron.
Problem ten występuje we wszystkich moich programach (obrabiam duże grafiki), na różnych typach drukarek. Obecnie używam kopiarek Canon iRA C5250i oraz iRA C7260i, lecz występował też na Canon iRA C5035i, Canon iRA C5235i, Minolta C250 oraz kilku innych. Nie jest to problem sterowników - różne sterowniki, różni producenci, różne komputery, różne programy a problem identyczny. Kopiarki czy z fiery i czy bez - problem ten sam.
Czy może to samo Delphi ma problem?
Pozdrawiam.

0

Nie do końca moje klimaty więc może napiszę coś nie do końca mądrego ale żeby "rozciągnąć" cokolwiek na płótnie to nie trzeba najpierw zadeklarować jest "obszaru".
A taki kod zadziała też poprawnie czy będą błędy:

procedure TForm1.Drukuj;
var R:TRect;
begin
   Obraz(typ);
   R:=Rect(500,1000,7000,4000);
   printer.Canvas.FillRect(R);
   printer.Canvas.StretchDraw(R,obr);
   R:=Rect(500,5000,7000,8000);
   printer.Canvas.StretchDraw(R,obr);
   R:=Rect(500,9000,7000,12000);
   printer.Canvas.StretchDraw(R,obr);
end;

Na stronie Embarcadero w przykładach dla StretchDraw najpierw i tak jest wywoływane FillRect http://docs.embarcadero.com/products/rad_studio/delphiAndcpp2009/HelpUpdate2/EN/html/delphivclwin32/Graphics_TCanvas_StretchDraw.html

0

A taki kod zadziała też poprawnie czy będą błędy:

procedure TForm1.Drukuj;
var R:TRect;
begin
   Obraz(typ);
   R:=Rect(500,1000,7000,4000);
   printer.Canvas.FillRect(R);
   printer.Canvas.StretchDraw(R,obr);
   R:=Rect(500,5000,7000,8000);
   printer.Canvas.StretchDraw(R,obr);
   R:=Rect(500,9000,7000,12000);
   printer.Canvas.StretchDraw(R,obr);
end;

Też są puste miejsca.
Wychodzi, że jeśli chcę mieć pewność, żeby na wydruku w danym obszarze pojawiła się grafika, to najpierw muszę użyć FillRect.
Jak wspominałem jeśli wydruk wyślę do pliku (drukarka Microsoft XPS) to błędów nie ma. Jeśli przed StretchDraw zapiszę wprost na dysk to pliki są poprawne, a na wydruku czasem grafik nie ma.

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