PosterMaker druckt riesig

Enthusiasten, die sich ihre Computer-Grafiken an die Wand hängen wollen, können jetzt mit dem PosterMaker in neue Dimensionen vorstoßen: Jedes Bild kann bis zu 1,62 mal 1,12 Meter ausgedruckt werden.

*Nach dem Programmstart u nd der Anzeige einer kleinen Info-Box kann mit einer File-Select-Box ein Bild ausgesucht werden.**

Das Programm ist in der vorliegenden Form auf Monochrom-Bildschirm eingestellt und kann keine Farbbilder konvertieren. Sie können also normale Bilder im Doodle-Format benutzen.

In zwei weiteren Alertboxen (Bild 1) werden Sie dann nach den Vergrößerungsfaktoren gefragt. PosterMaker kann in jede Richtung 2,4 oder 8 mal vergrößern, so daß die größte Stufe eine 64-fache Größe bedeutet. Nach einer kleinen Rückfrage (der Ausdruck dauert schon sehr lange) beginnt die Vergrößerung.

Dazu wird das Bild in Abhängigkeit von der gewünschten Vergrößerung in Blöcke unterteilt, die bis auf Bildschirmgröße gebracht werden. PosterMaker schickt dann den Schirm als Hardcopy an den Drucker. Ihnen bleibt nach Ausdruck aller Blöcke noch das Zusammenkleben der Teile und schon haben Sie Ihr Lieblingsbild riesengroß.

PosterMaker druckt jeweils zwei untereinanderliegende Blöcke auf eine Seite und schickt dann ein FormFeed. Somit sparen Sie sich die Hälfte der Klebestellen in vertikaler Richtung. Der Druckvorgang kann übrigens jederzeit durch Drücken einer beliebigen Taste unterbrochen werden. Vor der Ausgabe der gerade bearbeiteten Seite werden Sie gefragt, ob der Ausdruck wirklich abgebrochen werden soll. Ist ein komplettes Bild bearbeitet können Sie durch Auswahl in einer weiteren Alertbox andere Grafiken ausdrucken.

Bild 1: Alertboxen um die Vergrößerungsfaktoren zu bestimmen

Cut & Paste

Als kleine Hilfe beim Zusammenkleben ist in Bild 2 noch die Ausdruckreihenfol-ge für einige Vergrößerungsstufen angegeben. Nach dem gleichen Prinzip müssen Sie auch bei den anderen Vorgehen.

Das Programm in Modula-2 (Listing 1) macht ausgiebig Gebrauch von Rastercopies. Die Einzelheiten zu dieser Funktion wurden in der ST-Ecke in ST-Computer 11/87, Seite 76 erläutert. Hier wird sie auf zweierlei Weise verwendet.

Die Prozedur “SetUpPicScreen” reserviert 32000 Bytes im Speicher. Dieser Bereich kann vom VDI wie ein realer Bildschirm verwendet werden, wenn ein entsprechender Memory-Form-Defini-tion-Block definiert wurde. Das auszudruckende Bild wird nun in diesen “Speicherbildschirm” geladen und jeweils mit einer Rastercopy blockweise auf den realen kopiert, was in der Prozedur “Blow ItUp” geschieht.

Aber auch zum Vergrößern selbst läßt sich die Rasterco-py-Funktion einsetzen und sichert dabei eine schnelle Verarbeitung. Die Vorgehensweise dabei ist einfach. Bei der Vergrößerung in vertikaler Richtung auf das Doppelte geht die untere Bildschirmhälfte sowieso verloren. Wir nehmen also die letzte Bildschirmzeile der ersten Hälfte und kopieren sie einfach in die unterste Bildschirmzeile. Wird ihr Inhalt auch noch in die vorletzte Zeile kopiert, ist eine Pixelreihe vergrößert. Auf diese Art arbeitet sich die Prozedur “BlowUpV” bis zur ersten Bildschirmzeile hoch.

Bei der horizontalen Vergrößerung mit “BlowUpH” werden einfach alle Bildschirm spalten ab der Mitte bis an den linken Rand je zweimal kopiert.Eine kleineErläuterung verdient noch die Funktion “Power Of2”, die mit dem Parameter “a” zwei hoch a liefert. Der Trick dabei ist, daß die Standardroutine “INCL” benutzt wird. Sie setzt das Bit Nummer a in dem Bitvektor b. Wer sich im binären Zahlensystem auskennt, weiß sofort, daß dieser Bitvektor nun dem Wert zwei hoch a entspricht, und genau das liefert die Funktion als CARDINAL ab.

Bleibt nur noch zu hoffen, daß Sie für den PosterMaker genügend Farbbänder auf Vorrat haben und das Sägen Ihres Druckers auch auf längere Zeit ertragen können!

Bild 2: So müssen die Ausdrucke zusammengeklebt werden

MODULE PosterMaker; (* Robert Tolksdorf, 9.12.87 *) (* $ A+ *) (* Code optimieren *) FROM SYSTEM IMPORT ADR, ADDRESS ; FROM ASCII IMPORT FF ; FROM Strings IMPORT String, Length, Concat, InitStringModule ; FROM GEMDOS IMPORT Open, Read, Close, ConIS, NecIn, PrnOut, Alloc, Free ; FROM GEMAESbase IMPORT Arrow, MouseOff, MouseOn; FROM AESApplications IMPORT Appllnitialise, ApplExit; FROM AESForms IMPORT FormAlert, FileSelectorlnput ; FROM AESGraphics IMPORT GrafMouse ; FROM GEMVDIbase IMPORT VDIWorkInType, VDIWorkOutType, BigPxyArrayType ; FROM VDIControls IMPORT OpenVirtualWorkstation, CloseVirtualWorkstation; FROM VDIRasters IMPORT MFDBType, CopyRasterOpaque ; FROM XBIOS IMPORT ScreenPhysicalBase, ScreenDump ; CONST InfoAlert = '[0][ The Poster Maker| from ST-Computer|written Dez. 1987 by| Robert Tolksdorf| ][ OK ]'; HorizScale = ' [2] [Horizontal scaling][ 2x | 4x | 8x ]'; VertScale = ' [2] [Vertical scaling] [ 2x | 4x | 8x ]'; ReallyPrint = ' [3] [Really Start printing ?][ OK | Cancel ]'; AbortPrint = ' [2] [Really abort printing ?][ OK | Cancel ]'; Another = ' [2] [Another printout ?] [ Yes | No ]' ; DEBUG — FALSE; (* TRUE, wenn kein Pr int out *) VAR PicScreen, RealScreen : MFDBType; (* Screen Informationen *) PicScreenA, RealScreenA : ADDRESS; (* deren Adressen *) ApplID, ScreenHandle : INTEGER; (* AES/VDI ID's *) ScreenSize ; LONGCARD; (* Bildschirmgröße *) Scaling ; RECORD (* Vergrößerung *) Horiz, Vert : CARDINAL; END; (* Screen-Init, MFDB's setzen, Speicherbildschirm einrichten *) PROCEDURE SetUpPicScreen; VAR workin : VDIWorkInType; workout : VDIWorkOutType; i : INTEGER; BEGIN InitStringModule; i:=FormAlert(1,InfoAlert); FOR i: =0 TO 9 DO workin[i]:=0 END; workin[10]:=2; OpenVirtualWorkstation(workin,ScreenHandle,workout); WITH RealScreen DO pointer:=ScreenPhysicalBase(); width:=639; height:=399; widthW:=40; format:=1; planes:=1; END; RealScreenA:=ADR(RealScreen); PicScreen:=RealScreen; Alloc(ScreenSize,PicScreen.pointer); PicScreenA:=ADR(PicScreen); END SetUpPicScreen; (* File auswählen und eventuell in Speicherbildschirm laden *) PROCEDURE LoadPic(): BOOLEAN ; VAR inpath, insel, filename : String ; dummy : BOOLEAN ; exbutton, handle : INTEGER; status : (StillSelecting, Aborted, ReadIn); BEGIN GrafMouse(Arrow, NIL); status:=StillSelecting; REPEAT inpath:= '\*.*'; insel[0]:=0C; FileSelectorInput(ADR(inpath),ADR(insei),exbutton); IF (exbutton#0) AND (insel[0]#0C) THEN WHILE inpath[Length(inpath)-1]#'\' DO inpath[Length(inpath)-1]:=0C END; Concat(inpath,insel,filename); Open(filename,0,handle); IF handle>0 THEN Read(handle,ScreenSize,PicScreen.pointer); dummy:=Close(handle); status:=ReadIn; END; ELSE status:=Aborted; END; UNTIL (status#StillSelecting); RETURN (status=ReadIn); END LoadPic; (* Bild anzeigen u.mit Alerts VergröPerung auswählen *) PROCEDURE SelectScaling() :BOOLEAN; VAR pxy : BigPxyArrayType; BEGIN pxy[0]:=0; pxy[2]:=PicScreen.width; pxy[4]:=0; pxy[6]:=RealScreen.width; pxy[1]:=0; pxy[3]:=PicScreen.height; pxy[5]:=0; pxy[7]:=RealScreen.height; GrafMouse(MouseOff,NIL); (* Auf den realen Bildschirm kopieren *) CopyRasterOpaque(ScreenHandle,3,pxy,PicScreenA, RealScreenA); GrafMouse(MouseOn,NIL); Scaling.Horiz:=CARDINAL(FormAlert(1,HorizScale)); Scaling.Vert :=CARDINAL(FormAlert(1,VertScale)); RETURN (FormAlert(1,ReallyPrint)=1); END SelectScaling; (* Blockweise in den realen Bildschirm kopieren, vergrößern und ausdrucken. Bei Tastendruck eventuell abbrechen *) PROCEDURE BlowItUp; VAR i, hblock, vblock, hblocksize, vblocksize : INTEGER; pxy : BigPxyArrayType ; ch : CHAR; (* 2 hoch a ausrechnen *) PROCEDURE PowerOf 2 (a:CARDINAL) : CARDINAL; VAR b:BITSET; BEGIN b:={}; (* Trick mit BITSET: Das Bit # a *) INCL(b,a); (* wird gesetzt = 2 hoch a *) RETURN CARDINAL (b) ; (* und als CARDINAL zurückgegeben *) END PowerOf2; BEGIN hblocksize:=(PicScreen.width+1) DIV PowerOf2(Scaling.Horiz); vblocksize:=(PicScreen.height+1) DIV PowerOf2(Scaling.Vert); pxy[4]:=0; (* Destination-x und *) pxy[5]:=0; (* Destination-y sind immer 0 *) GrafMouse(MouseOff,NIL); (* blockweise ... *) FOR hblock:=1 TO PowerOf2(Scaling.Horiz) DO FOR vblock : =1 TO PowerOf 2 (Scaling.Vert) DO (* ... realen Bildschirm löschen ... *) pxy(0]:=0; pxy[2]:=RealScreen.width; pxy[6]:=RealScreen.width; pxy[1]:=0; pxy[3]:=RealScreen.height; pxy[7]:=RealScreen.height; CopyRasterOpaque(ScreenHandle,0,pxy,RealScreenA,RealScreenA); (* ... Block aus Speicher kopieren ... *) pxy[0]:=(hblock-1)*hblocksize; pxy[2]:=hblock*hblocksize-1; pxy[6]:=hblocksize-1; pxy[1]:=(vblock-1)*vblocksize; pxy[3]:=vblock*vblocksize-1; pxy[7]:=vblocksize-1; CopyRasterOpaque(ScreenHandle,3,pxy,PicScreenA, RealScreenA); (* ... vergrößern ... *) FOR i:=1 TO Scaling.Horiz DO BlowUpH; END; FOR i:=1 TO Scaling.Vert DO BlowUpV; END; (* ... Taste gedrückt ?? *) IF ConIS() THEN NecIn(ch); GrafMouse(MouseOn,NIL); IF (FormAlert(2,AbortPrint)=1) THEN RETURN (* Abbruch *) ELSE GrafMouse(MouseOff,NIL); END END; IF ~DEBUG THEN (* realen Bildschirm an Drucker schicken *) ScreenDump ; (* Seite voll -> FormFeed *) IF ~ODD(vblock) THEN PrnOut(FF); END; END; END; END; GrafMouse(MouseOn,NIL); END BlowItUp; (* realen Bildschirm horiz . a . d. Doppelte vergröPern *) PROCEDURE BlowUpH; VAR x : INTEGER; pxy : BigPxyArrayType; BEGIN pxy[1]:=0; pxy[3]:=RealScreen.height; pxy[5]:=0; pxy[7]:=RealScreen.height; FOR x:= ((RealScreen.width+1) DIV 2)-1 TO 0 BY -1 DO pxy[0]:=x; pxy[2]:=x; pxy[4]:=x*2; pxy[6]:=x*2; CopyRasterOpaque(ScreenHandle,3,pxy,RealScreenA, RealScreenA); INC(pxy[4]); INC(pxy[6]); CopyRasterOpaque(ScreenHandle,3,pxy,RealScreenA, RealScreenA); END; END BlowUpH; (* realen Bildschirm vertikal a.d.Doppelte vergröPern *) PROCEDURE BlowUpV; VAR y : INTEGER; pxy : BigPxyArrayType; BEGIN pxy[0]:=0; pxy[2]:=RealScreen.width; pxy[4]:=0; pxy[6]:=RealScreen.width; FOR y:=((RealScreen.height+1) DIV 2)-1 TO 0 BY -1 DO pxy[1]:=y; pxy[3]:=y; pxy[5]:=y*2; pxy[7]:=y*2; CopyRasterOpaque(ScreenHandle,3,pxy,RealScreenA, RealScreenA); INC(pxy[5]); INC(pxy[7]); CopyRasterOpaque(ScreenHandle,3,pxy,RealScreenA, RealScreenA); END; END BlowUpV; (* Speicher freigeben und Screen schliePen *) PROCEDURE CloseDown; VAR dummy: BOOLEAN ; BEGIN dummy:=Free(PicScreen.pointer); CloseVirtualWorkstation(ScreenHandle); END CloseDown; BEGIN ApplID:=ApplInitialise(); ScreenSize:=32000; SetupPicScreen; REPEAT IF (LoadPic()) AND (SelectScaling()) THEN BlowItUp; END; UNTIL (FormAlert(1,Another)=2); CloseDown; ApplExit; END PosterMaker.

Listing vom PosterMaker


Robert Tolksdorf
Aus:ST-Computer 08 /1988, Seite

Links

Copyright-Bestimmungen: siehe Über diese Seite