BCB - wyskalowanie podgladu wydruku

0

Witam,

Problem jest nastepujacy. Pisze program do wydruku blankietow. Wszystko mam, tylko nie wiem za bardzo jak zrobic podglad wydruku, tzn. wiem, ale utknalem na tym, jak odpowiednio wyskalowac obraz.

Moze najpierw napisze jak skaluje wydruk. Drukuje rysujac po Canvasie drukarki, wymiary przeliczam na mm, czyli cos takiego:

dl = printer->PageWidth;
szer = printer->PageHeight;

//DL_STRONY, SZER_STRONY - wymiary strony, ktora chce drukowac (210x297)

jedn_x = dl/DL_STRONY;
jedn_y = szer/SZER_STRONY;

Teraz majac wszystkie wymiary blankietu moge spokojnie to wydrukowac i umiescic w odpowiednim miejscu na stronie, na przyklad jezeli chce skoczyc 10 mm od lewej i 10 mm od gornej krawedzi to pisze tak:

printer->Canvas->MoveTo(jedn_x*10,jedn_y*10);

Jednak z podgladem wydruku sprawa nie wydaje mi sie juz tak prosta. Przykladowo, chcac miec powiekszenie 100 % musze to tak wyskalowac, zeby w kazdej rozdzielczosci podglad na monitorze mial takie wymiary jak na wydruku.

Wiem ze zamotalem troche, wiec krotko - mam 3 komponenty, na ktorych robie podglad: Panel do tla, na nim Image (na nim rysuje podglad), a wszystko do wrzucone do Scrollboxa.

Jak w takim przypadku:

  • obliczyc rozmiar Panela tak, aby na monitorze mial fizyczna dlugosc taka jak strona na wydruku (jezeli sie nie zmiesci, to nie szkodzi, po to jesc ScrollBox zeby przewijac widok) - nie wiem jak maja sie wpisywane rozmiary panela do jego rzeczywistej wielkosci na ekranie - to chyba bedzie zalezalo od rozdzielczosci, ale w jaki dokladnie sposob [???]

  • jezeli juz rozwiaze pierwszy problem, to i tak chyba nie moge wziac wymiarow panela/Image zamiast printer->PageWidth i printer->PageHeight, poza tym pojawia sie jeszcze problem przeskalowania rozmiarow czcionek i grubosci linii :|

Podpowie ktos? To nie jest w sumie problem z C++ (pewnie i tak pojdzie do Newbie :P ) ale umiescilem tuataj bo uzywam BCB.

0

i to Ci działa?? Zobaczysz jak będzie to wyglądało na drukarce z innym DPI niż ta, na której testujesz
hint
DPI - punkty na cal - pobierasz z płutna
DPI / 2.54 - punkty na cm
DPI / 25.4 - punkty na mm
DPI zarówno formy jak i drukarki pobierasz (kod jest na forum, goolu itp), przeliczasz ile mm ma punktów i rysujesz posługując się wymiarami w mm

0

No tak, masz racje nie pomyslalem o tym - testowalem na pdf creator, Microsoft document image writer i na mojej drukarce, ale mozliwe ze wszystkie mialy ustawione takie samo DPI...

czyli wystarczy pobrac dpi prosto z canvasa drukarki albo canvasa Image na ktorym podglad rysuje, jesli dobrze zrozumialem? (slabo juz mysle o tej porze, wiec tak pytam)

0

ResX = DPI / 25.4;
ResY = DPI / 25.4;
http://delphi.cartall.com.pl/Pytania/pyt17.htm tu masz dokładnie o DPI w pionie i poziomie

piszesz sobie procedurę (kod w Delphi bo nie wiem jak to będzie w BCB)

procedure Draw(ACanvas: TCanvas; Zoom: Word);
var
  mm: Double;

  function GetRes(ACanvas: TCanvas): Integer;
  begin
    Result := GetDeviceCaps(ACanvas.Handle, LOGPIXELSX);
  end;

  function ToPx(mm: Integer): Integer;
  begin
    Result := Trunc(mm * 10 * Zoom / 100);
  end;

begin
  mm := GetRes(ACanvas) / 25.4;
  //rysujemy kwadrat o wsp. (10, 10, 20, 20) w mm i odpowiednim zoomie
  ACanvas.Rectangle(ToPx(10), ToPx(10), ToPx(20), ToPx(20));
  //wszystko co tak narysujesz będzie wyglądało tak samo niezależnie od tego gdzie to narysujesz. Oczywiście licz się z tym, że np, kwadrat na monitorze nie do końca wygląda jak kwadrat :)
end;
0

Ok, chyba zalapalem o co chodzi, ale twoj kod chyba nie bedzie dzialac w takiej postaci jak podales, bo nie uwzgledniasz LOGPIXELY...

Wprawdzie nie znam sie za bardzo na Delphi, ale zmienna mm jest zadeklarowana globalnie (?) jako double, ale nigdzie nie jest uzyta (?) bo funkcja ToPx uzywa mm typu calkowitego a nie zmiennej globalnej (?)

Niewazne zreszta, w kazdym razie - dzieki za naprowadzenie.

0
othello napisał(a)

Ok, chyba zalapalem o co chodzi, ale twoj kod chyba nie bedzie dzialac w takiej postaci jak podales, bo nie uwzgledniasz LOGPIXELY...

bo to nie jest cały kod. Jak dobrze popatrzysz to rozdzielczość X i Y są w większości przypadków takie sam, a jak się różnią to wygląda to mniej więcej tak RX = 300 RY = 298 więc jeśli nie musisz mieć super dokładnie to można pominąć sprawdzanie obu i wziąć tylko RX

Wprawdzie nie znam sie za bardzo na Delphi, ale zmienna mm jest zadeklarowana globalnie (?) jako double, ale nigdzie nie jest uzyta (?) bo funkcja ToPx uzywa mm typu calkowitego a nie zmiennej globalnej (?)

bo to błąd spowodowany późną porą itp

  function ToPx(m: Integer): Integer;
  begin
    Result := Trunc(mm * m * Zoom / 100);
  end;
0

Ok, mozna powiedziec ze juz sobie poradzilem, robie tak i chyba dziala ok:

jedn_x = (GetDeviceCaps(c->Handle,LOGPIXELSX))/25.4*(zoom/100.0);
jedn_y = (GetDeviceCaps(c->Handle,LOGPIXELSY))/25.4*(zoom/100.0);

W sumie wiele przeprawiania nie bylo - tylko kwestia zdefiniowania przelicznika.

Ale jeszcze jedno pozostaje do zrobienia - obliczenie, jakie wymiary Image ustawic tak, zeby zmiescil sie caly blankiet (Image jest w ScrollBox).

Zakladajac, ze obliczylem jedn_z i jedn_y biorac Canvas Image po ktorym rysuje robie tak:

podglad->Width = bWidth*jedn_x;
podglad->Height = bHeight*jedn_y;

gdzie bWidth i bHeight to wymiary blankietu w mm.

Oczywiscie naprawde to wyglada troche inaczej, bo mam zdefiniowana klase, ktora zajmuje sie wydrukiem.

0
othello napisał(a)

Ale jeszcze jedno pozostaje do zrobienia - obliczenie, jakie wymiary Image ustawic tak, zeby zmiescil sie caly blankiet (Image jest w ScrollBox).

Zakladajac, ze obliczylem jedn_z i jedn_y biorac Canvas Image po ktorym rysuje robie tak:

podglad->Width = bWidth*jedn_x;
podglad->Height = bHeight*jedn_y;

gdzie bWidth i bHeight to wymiary blankietu w mm.

możesz sobie trochę dodać na jakiś margines i wiesz, że jeszcze trzeba zmienić Image->Picture->Bitmap->Width i Height (albo jakoś tak to było) bo sama zmiana wymiarów Image'a nie zmieni Ci rozmiaru obszaru po którym możesz rysować

0

Dokladnie, teraz tylko zrobic wypelnianie tego blankietu i gra gitara.

Ciekawe, ze na allegro takie programy chodza chyba po okolo 15 zl z tego co widzialem.

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