← ST-Computer 04 / 1988

Selbstbau eines Computerscanners

Hardware

Das Wort “Scanner” kommt aus dem Englischen. “To scan” bedeutet abtasten oder auch ĂŒberfliegen. Der Hobby Computeranwender versteht darunter ein GerĂ€t, das Bild-Vorlagen in (s)einen Computer einliest.

Im Gegensatz zu den schnellen Video-Digitizern wird beim Scanner eine lichtempfndliche Photozelle in kleinen AbstĂ€nden ĂŒber eine Vorlage gefĂŒhrt. FĂŒr jeden Abtastschritt werden dem Computer Helligkeitsdaten ĂŒbermittelt. So wird die Vorlage Zeile um Zeile eingelesen.

Ausgehend davon kam ich - wie sicherlich andere schon vor mir - auf den Gedanken daß die Photozelle von meinem Drucker fortbewegt werden könnte. Dazu genĂŒgt es, sie in ein altes FarbbandgehĂ€use einzubauen. Mit einer kleinen Sequenz von Steuerzeichen lassen sich die meisten Drucker zum Scannen zweckentfremden. Nach einigen hundert Horizontalschritten folgt ein WagenrĂŒcklauf, um die nĂ€chste Zeile zu lesen. Die Vorlagen mĂŒssen sich hierbei alle in den Drucker einspannen lassen. Wer einen Flachbettplotter sein eigen nennt, kann z.B. auch PlattenhĂŒllen bequem abtasten. Ein Plotter macht außerdem keine Anstalten bei der Ansteuerung. Einige Drucker zeigen, dank modernster Wegeoptimierung, ein großes Maß an Starrsinn. Manche GerĂ€te versalzen selbst einem trickreichen Programmierer die Suppe, indem sie stets einen WagenrĂŒcklauf abwarten und dann emsig, aber viel zu schnell ĂŒber die Vorlage flitzen.

Folgendes wird also zum Scannen benötigt:

  1. Ein (einfacher) Drucker oder ein Plotter
  2. Eine Photozelle mit logarithmischem A/D-Wandler
  3. Scannersoftware mit USM-Algorithmen zum Verdoppeln der BildschÀrfe
  4. Scannenswerte Vorlagen

Die Sache sieht also nicht besonders schwierig aus, zumal meine komfortable Scannersoftware als Public Domain erhÀltlich ist.

Nur DM 25,- habe ich fĂŒr meine Elektronik berappt. Nach 4-stĂŒndiger Nachtarbeit funktionierte der A/D-Wandler perfekt. Aber dann gab es doch Schwierigkeiten: Die ersten eingescannten Bilder wirkten unscharf und "verrauscht”.

Erst nach und nach gelang, hauptsÀchlich durch verbesserte Software, ein Scanner mit erstaunlicher BildqualitÀt.

Die Hardware war, abgesehen von einem kleinen Wackelkontakt, nicht weiter zu verbessern. Die umgewandelten Helligkeitswerte entsprechen, wegen der logarithmischen Kennlinie vom A/D-Wandler, dem tatsĂ€chlichen Graueindruck. Die Vorlagen werden außerdem nicht, wie bei vielen Billigscannern, mit Infrarotlicht abgetastet, sondern mit sichtbarem Licht.

Meine Scannersoftware bietet also einige Leckerbissen:

Das abgetastete Originalbild kann vergrĂ¶ĂŸert, verkleinert und gestaucht werden. Auch Helligkeit, Kontrast und Gradation sind nachtrĂ€glich zu verĂ€ndern. So kann man z.B. die dunklen Bildbereiche verĂ€ndern, ohne daß sich die hellen und mittelgrauen Töne verĂ€ndern.

Die Grauabstufungen sind auf dem s/w-Monitor nur durch FĂŒllmuster darstellbar. Diese Muster sind besonders fein, um ein möglichst realistisches Bild zu erzeugen. Ich habe auch darauf geachtet, daß keine “Kanten-Effekte” zwischen verschiedenen Mustern auftreten.

Die USM-Funktionen (USM = Un-scharf-Maskierung) betonen feine Bilddetails, die beim Abtasten teilweise verloren gingen. Außerdem wird die “Treppchenbildung” vermieden. Diese Funktion kann tatsĂ€chlich den SchĂ€rfeeindruck verdoppeln. Das ist etwas, was andere Scannersoftware nicht bieten kann.

Das so aufbereitete Bild lĂ€ĂŸt sich im Degas- oder BinĂ€rformat auf Diskette abspeichern. Die Bilder können so mit einem Malprogramm noch weiter verschönert werden.

Mit einer geplanten Version 2.0 kann man in die Farbauflösung umwandeln und die Bilder sogar einfÀrben.

Hardware

Die Hardware besteht im wesentlichen aus einem Phototransistor, dem logarithmischen VerstÀrker und dem 4-Bit-A/D-Wandler.

Die Hardware wird mit dem Joystick-Port verbunden und die Elektronik ĂŒber diesen Stecker auch mit 5 Volt versorgt. Man bekommt einen solchen Joystick-Stecker im Elektronik-Laden (9-polige D- Buchse). Man muß nur den Metallrahmen entfernen. Zur Not hilft auch das Kabel eines alten Joysticks.

Ich möchte nun ganz kurz die Funktionsweise meiner Schaltung erklÀren:

Der Phototransistor T3 (BPY 14) liefert einen zur LichtstÀrke proportionalen Ausgangsstrom. T1 logarithmiert diesen Strom und wandelt ihn in eine Gleichspannung (maximal 0,7 Volt) um.

Widerstand R2 und C1 filtern Brummspannungen aus. Der nun folgende OP verstĂ€rkt diese Spannung. Hier sind die Regler fĂŒr Abtasthelligkeit (P2) und Kontrast (P1) angebracht.

Transistor T2 steuert eine Leuchtdiode an. Diese LED leuchtet in AbhĂ€ngigkeit von der “gesehenen” Helligkeit auf.

Das Platinenlayout im Maßstab 1:1
Das Platinenlayout im Maßstab 1:1

Alle ĂŒbrigen ICs dienen zur A/D-Wandlung. Der Eingang befindet sich an IC 1 Pin 6. Beim Aufbau sollte man darauf achten, daß C4, R11 und R10 nicht zu weit weg von IC2 plaziert werden. Man sollte die Digita1-Masse (breites Symbol) und Analog-Masse (schmales Symbol) getrennt verdrahten und erst an C6 miteinander verbinden.

Die gesamte Elektronik wurde auf einer Lochrasterplatine von 30 mm * 80 mm aufgebaut. Man tut sich bei der doppelten PlatinenflĂ€che allerdings weniger schwer. IC-Fassungen fĂŒr IC2, IC3 und IC4 sind kein Luxus, denn die CMOS-ICs sollten erst zum Schluß eingesetzt werden, um deren Zerstörung durch statische ElektrizitĂ€t zu vermeiden.

Ist die Platine fertig bestĂŒckt, wird der Phototransistor ĂŒber ein lĂ€ngeres abgeschirmtes Kabel angeschlossen. Die Transistorbasis ist nicht belegt. Dieses Anschlußbeinchen wird gekĂŒrzt.

Der Phototransistor hat eine Linse. Der Öffnungswinkel betrĂ€gt nur 20°. Daher wird schrĂ€g einfallendes Licht nicht gesehen. Wegen der BildschĂ€rfe muß man diesen Blickwinkel noch weiter einengen. Normalerweise wird mit einem Pixelabstand von ca. 1mm gescannt.

Dazu baut man den Phototransistor z.B. in eine KugelschreiberhĂŒlse oder Ă€hnliches ein. Das Öffnungsloch an der Spitze sollte zwischen 0.5 und 1 mm groß sein. Der Phototransistor hat dabei einen Mindestabstand von ca. 10mm zur Öffnung. GrundsĂ€tzlich gilt, daß kleine Vorlagen auch kleine Öffnungen benötigen. Ist die Öffnung aber zu klein, verschwinden u.U wichtige Bilddetails in den AbtastzwischenrĂ€umen. U.U. ist dann der Phototransistor BPW 13 (=BPW 14 ohne Linse) besser geeignet. Alternativ kann der Phototransistor auch in eine ausgediente Farbbandkassette eingepaßt werden. Man bohrt an geeigneter Stelle ein kleines Loch mit oben erwĂ€hntem Durchmesser in die Kassette.

Die Abtastöffnung muß einerseits möglichst nahe an der Vorlage angebracht sein, andererseits darf sie nicht das Abtastlicht unterbrechen. Kunststoffe sind meistens etwas lichtdurchlĂ€ssig. Deshalb sollte man das Ganze mit schwarzem Isolierband ©umwickeln bzw. schwarz lackieren. Wenn man das Öffnungsloch verschließt, darf die Schaltung nicht mehr auf das Außenlicht reagieren. Wenn der Phototransistor nicht genĂŒgend gegen Fremdlicht abgeschirmt wird, erhĂ€lt man unscharfe Bilder. Es empfiehlt sich also, die oben erwĂ€hnten Tips beachten.

Bild 1: Das Schaltbild
Bild 1: Das Schaltbild

Die Software

Die Software wurde in GFA-BASIC erstellt. Das Scanner-Programm ist Public Domain - also fĂŒr jeden zugĂ€nglich.

Wie bereits erwĂ€hnt, wird die Scanner-Hardware am Joystick-Port betrieben. Mein Scannerprogramm fragt diesen Port mit einem ganz ordinĂ€ren “Peek”-Befehl ab. Das mag zwar die GEM-Spezialisten etwas schockieren, aber das gibt uns die Möglichkeit, auch andere Hardware durch Ändern dieser Peek-Adresse an anderen Ports einzusetzen.

Zum Scannen muß man einen Druckertreiber laden und diesen der Bildvorlage entsprechend modifizieren. Konkret ist wohl stets die Schrittzahl horizontal und vertikal an die jeweiligen Vorlagen anzupassen. Die Schrittweite (PixelabstĂ€nde) sollte ebenfalls auf die VorlagengrĂ¶ĂŸe eingestellt werden.

Wenn alle ĂŒbrigen Vorbereitungen getroffen sind, kann die Abtastung gestartet werden. Auf dem Bildschirm sieht man Zeile um Zeile ein unscharfes “Urbild” entstehen. Der Abtastvorgang kann, falls erforderlich, jederzeit mit der ESC-Taste gestoppt werden.

Wenn der Abtastvorgang beendet ist, wird das Urbild abgespeichert. Hat man das getan, kommt die Aufbereitung. Man verÀndert jetzt Helligkeit, Kontrast, BildschÀrfe und zoomt bzw. entzerrt das Bild.

Danach speichert man das aufbereitete Bild als Neochrome- (erst ab Version 2.0) oder Degas-File ab.

Die Malprogramme Degas (und Neochrome) helfen, das Bild weiter zu verbessern. Auch Fotomontagen sind möglich.

Die Bedienung des Scannerprogramms erklĂ€rt sich praktisch von selbst. Einige Punkte muß ich jedoch noch erwĂ€hnen:

  1. Alle Funktionen und MenĂŒpunkte sind mausgesteuert. ZusĂ€tzlich kann die rechte Maustaste einige MenĂŒpunkte direkt auf dem Bildschirm auswĂ€hlen (z.B. aus dem Druckertreiber).
  2. Eingaben mĂŒssen mit der < Return >-Taste beendet werden.
  3. Zusammen mit dem Drucker treiber speichert bzw. lÀdt man auch alle Bildkorrekturdaten.
  4. Der eigentliche Druckertreiber (im MenĂŒ ganz oben) schickt folgende vier unterschiedlichen Zeichenketten a den Drucker: 4.1 Zuerst wird der Drucker initialisiert. Dies geschieht einmalig vor der Abtastung und stellt Geschwindigkeit, VorschĂŒbe oder Ă€hnliches eil Diese Zeichenkette wird unte dem MenĂŒpunkt “Initialisieren” eingegeben. 4.2 WĂ€hrend der Abtastung wird fĂŒr jeden horizontalen Vorschub die 2. Zeichenkette (“Hör. Vorschub”) ausgegeben. 4.3 FĂŒr jede neue Zeile muß ein WagenrĂŒcklauf und ein Zeilenvorschub erfolgen. Das erledigt die dritte Zeichenkette. (“Vert. Vorschub”) 4.4 Die vierte Zeichenkette soll den Drucker wieder in den normalen Betriebszustand zurĂŒckstellen. Sie wird unter “Abschluß” eingegeben.

Um “Bildstörungen” bzw. UnschĂ€rfe zu verhindern, sind zwei einstellbare Verzögerungszeiten (Abtastung horizontal und vertikal) vorhanden.

Der Treiber wird wie folgt ediert:

< ‘ > Dient nur zur optischen Trennung einzelner Zeichen. Die Zeichenketten werden da durch etwas ĂŒbersichtlicher. Dieses Zeichen wird spĂ€ter ĂŒbergangen.

< & > weist das Programm an, die nÀchsten zwei Zeichen als einen hexadezimalen ASCII-Code zu betrachten.

Beispiel:

Eingabestring “T’ex&74'&0D” wird zum Ausgabestring “Text” + < WagenrĂŒcklauf >.

Scanner - Praxis

1. Ausleuchten der Vorlage

Der verwendete Phototransistor BPY 14 reagiert auf sichtbares Licht. Eine gewöhnliche Tischlampe sorgt fĂŒr ausreichende Belichtung der Vorlage. Der Phototransistor selbst hat nĂ€mlich keine eingebaute Lichtquelle.

Beim Ausleuchten ist unbedingt folgendes zu beachten:

  • Die Vorlage muß gleichmĂ€ĂŸig ausgeleuchtet werden. Die Ausleuchtung wird durch Abtasten eines weißen Blatt Papiers kontrolliert. Hierbei stellt man in Blattmitte mit dem Abtasthelligkeitsregler an der kleinen Elektronik etwa 8 Helligkeitspunkte ein und fĂ€hrt anschließend an die PapierrĂ€nder. Die Helligkeitswerte dĂŒrfen sich nur unwesentlich verĂ€ndern.
  • Fremdlicht muß man abschirmen. Ein nahes Fenster beleuchtet mit. Wenn nun plötzlich Wolken aufziehen, kommt es zu einem horizontalen Schattenstreifen.
  • Reflexionswinkel unbedingt vermeiden. Die oftmals glĂ€nzenden Vorlagen reflektieren wie ein Spiegel. Schlimmstenfalls sieht unser Scanner dann nur noch eine GlĂŒhbirne bzw. Neonröhre.
  • Beim Flachbettplotter hat es sich bewĂ€hrt, die Photozelle um 45° zu neigen. Dadurch wirft sich die Photozelle selbst keinen Schatten. Die Belichtungslampe hat einen Abstand von ca. 80 cm und steht senkrecht ĂŒber der Vorlage.
  • Beim Drucker gibt es weniger Reflexionsprobleme, denn auf der gewölbten Vorlage konzentriert sich die Reflexion auf einer Linie. Die Lichtquelle (senkrecht ĂŒber der Walze) darf wesentlich nĂ€her ĂŒber der eingespannten Vorlage sein. 30 cm Abstand genĂŒgen zur gleichmĂ€ĂŸigen Ausleuchtung.

2. Einstellen von Abtasthelligkeit und Kontrast

Wie bereits in der Schaltungsbeschreibung erwĂ€hnt, bietet schon die Elektronik eine Möglichkeit die Abtasthelligkeit und den Abtastkontrast zu verstellen. Diese Einstellregler mĂŒssen immer der jeweiligen Vorlage angepaßt werden.

Helligkeit und Kontrast verhalten sich genau so, wie man es von einem FernsehgerÀt her kennt:

Zu wenig Kontrast lĂ€ĂŸt das Bild grau in grau erscheinen (hellgrau war weiß, dunkelgrau war schwarz). Bei zu viel Kontrast wirkt das Bild “hart”. Es fehlen die Mitteltöne (dunkelgrau wird zu schwarz und hellgrau wird zu weiß).

Der Helligkeitsregler hebt oder senkt die Helligkeit aller Bildinhalte gleichmĂ€ĂŸig.

Zum Angleich der Regler an die Vorlage geht man zunĂ€chst von der Mittelstellung aus. Danach muß zuerst die Helligkeit (P2) und dann der Kontrast (P1) eingestellt werden. Man wiederholt die Einstellung von Helligkeit und Kontrast mehrmals, bis fĂŒr die hellste Bildpartie (weiß) die Zahl 14 und fĂŒr die dunkelste die Zahl 1 angezeigt werden.

Die Helligkeitszahl wird rechts unten im DruckermenĂŒ stĂ€ndig angezeigt. Hierbei bedeutet die Zahl 0 das dunkelste Schwarz und die Zahl 15 das hellste Weiß. Es ist also auch möglich, den vollen Zahlenbereich auszuschöpfen indem man die Regler auf 0 bzw. 15 einstellt. Dabei ist es jedoch nicht immer einfach, die Einstellung zu kontrollieren, da ein Weiterdrehen der Regler keine Änderung (kleiner als Null oder grĂ¶ĂŸer als 15) bewirkt. Beim Abgleichen von Helligkeit und Kontrast kommt es darauf an. daß die Photozelle auch tatsĂ€chlich auf einen sehr hellen bzw. dunklen Bildpunkt gerichtet ist. Hat man diese beiden Stellen im Bild ausfindig gemacht, wird wĂ€hrend des Abgleichs immer zwischen diesen beiden Stellen hin und her gefahren, und dabei wird mit den Reglern auf 14 (wenn hell) und 1 (wenn dunkel) abgestimmt. ErfahrungsgemĂ€ĂŸ ist der Kontrastabgleich unkritischer als der Helligkeitsabgleich. Eine Abweichung von +-1 Helligkeitszahl ist nicht so schlimm, denn das fertig abgetastete Bild lĂ€ĂŸt sich in Helligkeit und Kontrast nachtrĂ€glich verĂ€ndern. Der MenĂŒpunkt hierfĂŒr heißt “Umfang”.

3. Einstellen der Bildformate (Druckertreiber)

Vor der Abtastung muß man sich ĂŒber die gewĂŒnschte BildgrĂ¶ĂŸe auf dem Bildschirm im klaren sein.

Zwar bietet meine Software auch eine Möglichkeit, das Bildformat nachtrĂ€glich zu verĂ€ndern bzw. zu verzerren. Aber die besten Ergebnisse bekommt man, wenn man das Bild etwa in der OriginalgrĂ¶ĂŸe belĂ€ĂŸt.

Also zĂŒckt man besser vorher den Taschenrechner:

Sicher weiß jeder, daß die monochrome Auflösung 640 x 400 Pixel betrĂ€gt. GrundsĂ€tzlich sollte man fĂŒr etwa vier Monitorpixel einen Abtastschritt vorsehen. Soll z.B. das Monitorbild vollstĂ€ndig “gefĂŒllt” werden, wĂ€ren das etwa 320 Abtastpunkte horizontal und 200 Punkte vertikal. (Zwei horizontale mal zwei vertikale Bildpixel kommen auf ein Urpixel). FĂŒr den Preis eines unscharfen Bildes verkĂŒrzt sich die Abtastzeit, wenn man ĂŒber dieses VerhĂ€ltnis hinausgeht. Ein Erhöhen der Abtastpixelzahl bringt hingegen keine nennenswerte Verbesserung der BildqualitĂ€t mehr.

Die USM-Routinen in meinem Programm sind bei einem Urpixel/Bildpixel-VerhĂ€ltnis von 1:4 optimal. USM bringt augenscheinlich die volle SchĂ€rfe wieder zurĂŒck.

An dem folgenden Beispiel möchte ich erklĂ€ren, wie der Druckertreiber eingestellt werden muß:

  • Ein Bild von der GrĂ¶ĂŸe 100 * 100 mm soll auf 150 * 150 Bildschirmpixel gescannt werden.
  • Dazu mĂŒssen 75 * 75 Abtast-Pixel (=Urpixel) eingescannt werden.
  • Die Schrittweite horizontal betrĂ€gt 100 mm / 75 = 1.33 mm
  • Die Schrittweite vertikal betrĂ€gt ebenfalls 1.33 mm
  • Der Druckertreiber wird entsprechend der obigen Vorgabe eingestellt. Horizonta1-und Vertikalvorschub lassen sich auf 1.4 mm einstellen. Das ist nahe genug am Wunschwert 1.33 mm. Das abgetastete Bild fĂ€llt also etwas kleiner als gewĂŒnscht aus. Mit der Option “Zoom” kann das Wunschformat spĂ€ter genau erreicht werden.
  • Da das Urpixel etwas grĂ¶ĂŸer geraten ist, benötigt man auch weniger Abtast-Schritte: 100 mm / 1.4 mm = ca. 71 Schritte
  • Die Schrittzahlen sind unter Schrittzahl horizontal bzw. vertikal einzugeben.
  • Die Abtastöffnung der Photozelle wĂ€hlt man etwas kleiner als die Schrittweite (Hier also ca. 1mm Durchmesser).
  • Die Steuercodes fĂŒr den Druckertreiber werden fĂŒr die Abtastschrittweite 1,4 mm ediert. Diese Zeichenkette paßt den Drucker- (bzw. Plotter-) Typ an.

4. Aufbereiten und Verschönern des Urbildes

Die Abtastbilder (Urbilder) können auf Diskette gesichert werden. Vielleicht befinden sich schon einige auf Ihrer PD-Diskette. Diese lassen sich betrachten, indem man sie mit “Lade Urbild” lĂ€dt und mit “Zeige Urbild” darstellt.

Das Urbild ist noch unscharf und Gradation, Helligkeit und Kontrast entsprechen noch dem Urzustand. Jedes Urbild kann aber mit den folgenden Optionen verbessert werden:

  • USM breit: Normalerweise sind Eigaben von ca. 5 praxisgerecht. Gibt man 0 ein, bleibt die SchĂ€rfe auf Urbildniveau. “USM breit” arbeitet auf Urpixel-Ebene und verstĂ€rkt dĂŒnne Linien und kleine Punkte. Es funktioniert nur, wenn die Abtastöffnung der Photozelle stimmt (Sie muß etwas kleiner als die Abtastschrittweite sein).
  • USM schmal: Auf Werte um die Zahl 5 stellen. “USM schmal” arbeitet auf Bildschirmpixel-Ebene (also 1/4 Urpixel) und verhindert u.a. die “Treppchen-Effekte” an diagonal verlaufenden Kanten. Auch hier muß die Breite der Abtastöffnung stimmen.
  • Umfang: Funktioniert analog zu Helligkeit und Kontrast mit dem Vorteil, daß sich die beiden Einstellungen nicht beeinflussen. Licht wirkt nicht auf dunkle Bildinhalte und umgekehrt. Wenn Abtastkontrast und -helligkeit gestimmt haben, gibt man hier die Zahl 0 ein, ansonsten zwischen +-5.
  • Gradation: Ähnlich wie Umfang. Diese Einstellungen wirken aber nur auf ganz bestimmte Helligkeitsbereiche. Normalerweise stellt man 0 ein. Falls erforderlich, gibt man Werte bis +-5 ein. Positive Zahlen erhöhen stets die Helligkeit und umgekehrt. Die Gradation verĂ€ndert hellere, mittelhelle und dunkle Grautöne unabhĂ€ngig voneinander.

Ich wĂŒnsche noch viel Spaß beim Basteln und hoffe, daß mein kleines Programm Verwendung findet.

Der Autor selbst
Der Autor selbst

Ein Listing des Source-Codes kann man bei mir anfordern (ca. DM 20,-).

Ralf Bager Friedensstr. 10 b 6082 Mörfelden-Walldorf

PS: Es gibt bekanntlich verschiedene TOS-Versionen. Deshalb ist es z.B. beim neuen Blitter-TOS oder beim uralten Disketten-TOS erforderlich, die “Joystick Peek-Adresse” zu Ă€ndern. Sonst tappt Dein Scannner im Dunkeln. Man kann diese Funktion mit einem normalen Joystick ĂŒberprĂŒfen.

Dim T$(65),Dr$<65)
Dim W(65)
Dim Wert%(256)
@Men_init
@Full_init
0Anz_init
@Do_var
Urbild$=Space$(32767)
Bild$=Space$(32767)
Eflag=0 
W(23)=3593 
T$(23)=Str$(W(23))
'
'
Start:
@Tx
Menu Rollo$()
On Menu Gosub Menue
'
'
Do
	On Menu 
	If Menu(12) =2 
		Repeat 
			On Menu 
		Until Menu(12)=0 
		@Mausklick(Menu(10),Menu(11))
	Endif
	Joy2=Peek(W(23))
	If Joy2<>Joy1 
		Joy1=Joy2
		Print At (58,24);Joy1;" "
	Endif
Loop
'
'
Procedure Mausklick (X, Y)
	Menu Off 
	local I 
	X=Int(X/8)
	Y=Int(Y/16)+1 
	For I=27 To 65
		If Anz%(0,I)+38>X And Anz%(0,I)<X And Anz%(1,I)=Y 
			Mreq=I 
			@Menue 
			Mreq=0 
		Endif 
	Next I 
Return
'
'
Procedure Menue 
	If Mreq=0 
		Me=Menu(0)
	Else
		Me=Mreq
	Endif
	On Me Gosub About
	On Me-10 Gosub N,Drlad,Urlad,N,Drspei,Urspei,Binspei, Neospei,Degspei
	On Me-20 Gosub Kopie, N, Zin,N,N,N,Txin,Txin, Txin,Txin 
	On Me-30 Gosub Zin, Zin, N, Zin, Zin, N,N, Zoom, N, Zin 
	On Me-40 Gosub Zin,N,Zin,Zin,Zin,N,Zin,Zin 
	On Me-50 Gosub Bildcalc, Scan,N,N,N,Par_bild, Scan_bild, N,Ende 
	Menu Off 
Return
'
'
Procedure About 
	Local A
	Alert 0,"* * S C A N N E R * *|C. 1987|Ralf Bager,Mörfelden", 1, "OK", A
Return
'
'
Procedure Drlad 
	Local Du$
	Fileselect "\*.DR1", "", Nam$
	If Nam$<>""
		If Exist (Nam$)
			Open "I",#1,Nam$
			For I=10 To 65
				If I<>34 And I<>35 
					Line Input #1,T$(I)
				Else
					Line Input #1,Du$
				Endif 
			Next I
			Close #1 
		Else
			Alert 3,"Datei nicht vorhanden !| | ",1,"OK",Du
		Endif
	Endif
	@Tx
Return
'
'
Procedure Urlad 
	Local Len
	Fileselect "\*.UR1","",Nam$
	If Nam$<>""
		If Exist (Nam$)
			Urbild$=Space$(32767)
			Bload Nam$, Varptr (Urbild$)
			Len=Cvl (Left$(Urbild$, 4))
			T$(34)=Mid$(Urbild$, 5,4)
			T$(35)=Mid$(Urbild$, 9,4)
			Urbild$=MidS(Urbild$, 13, Len)
		Else
			Alert 3, "Datei nicht vorhanden !|	|	",1,"OK",Du
		Endif 
	Endif 
	@Tx
Return
'
'
Procedure Urspei 
	Local Len
	Fileselect "\*.UR1","",Nam$
	If Nam$<>""
		Len=Len(Bild$)
		Urbild$=Mkl$ (Len(Urbild$)) +Right$("   "+T$(34),4)+Right$("   "+T$(35), 4)+Urbild$
		Bsave Nam$,Varptr(Urbild$),Len+12 
		Urbild$=Mid$(Urbild$, 13, Len)
	Endif
Return
'
'
Procedure Drspei
	Fileselect "\*.DR1", "",Nam$
	If Nam$<>""
		Open "O",#1,Nam$
		For I=10 To 65 
			Print #1,T$(I)
		Next I
		Close #1 
	Endif 
Return
'
'
Procedure Kopie 
	@All 
	If Erg=2 
		Hardcopy 
	Endif 
Return
'
'
Procedure Scan 
	Local A$
	Cls
	@All
	If Erg=2 
		@Disl 
		@Do_var 
		@Full_lut 
		Cls
		@Do_scan
	Endif
	Repeat
		A$=Inkey$
	Until A$=Chr$(27)
	Cls
	Menu Rollo$()
	@Tx
Return
'
'
Procedure Ende 
	Menu Kill 
	End 
Return
'
'
Procedure Zin 
	Local M 
	M=Me
	@Textedit(Anz%(0,M)+18,Anz%(1,M),4,T$(M),-1)
	T$(M)=Rueck$
Return
'
'
Procedure Txin 
	Local M 
	M=Me
	@Textedit(Anz%(0,M)+18,Anz%(1,M),60,T$(M),0)
	T$(M)=Rueck$
Return
'
'
Procedure Bildcalc 
	Local X,Y,P,B,A$
	Cls
	@Disl
	@Do_var
	@Full_lut
	Cls
	@Rahmung(0)
	For Y=0 To (W(35)-1)
		For X=0 To (W(34)-1)
			P=(Y*W(34)+X)/2
			B=Asc(Mid$(Urbild$, Int(P),1))
			If P-Int(P)>0.1 
				B=(B And 240)/16 
			Else
				B=B And 15 
			Endif
			@Putpix(X*2,Y*2,2,2,B*16)
		Next X
	Next Y 
	@Rahmung(1)
	Repeat
		A$=Inkey$
	Until A$=Chr$(27)
	Cls
	Menu Rollo$()
	@Tx
Return
'
'
Procedure Par_bild 
	Cls
	Menu Rollo$()
	@Tx
Return
'
'
' ______________________________
' ab hier kommen untergeordnete Proceduren
' ______________________________
'
'
Procedure Tx 
	Local M 
	For M=0 To 65 
		If Anz%(0,M)>0
			@Str_clean(Rollo$(M))
			Print At(Anz%(0,M),Anz%(1,M));Rueck$;":"
			Print At(Anz%(0,M)+18,Anz%(1,M));T$(M);
		Endif 
	Next M 
Return
'
'
Procedure Str_clean (A$)
	Local B$, I
	For I=Len(A$) To 1 Step -1 
		B$=Mid$(A$,I,1)
		Exit If B$<>"-" And B$<>" " And B$<>"
	Next I
	A$=Left$(A$,I)
	If Left$(A$,1)<>"-"
		Rueck$=Left$(A$+"............",	17)
	Else
		Rueck$=A$
	Endif
Return
'
'
Procedure Do_var
	Local I,K,A$,B$,C$
	Eflag=1
	If W(34)*W(35)/2>32767 
		Error 10 
	Endif
	For I=0 To 65 
		A$=Rollo$(I)
		B$=T$(I)
		If Len(A$)>0 And Anz%(0,I)<>0 And Left$(A$, 1)<>"-"
			If I<27 Or I>30 
				W(I)=Val(B$)
			Else
				Dr$ (1)=""
				For K=1 To Len CBS)
					C$=Mid$(BS,K,1)
					If C$<>"'"
						If C$<>"&"
							Dr$(I)=Dr$(I)+C$
						Else
							Dr$(I)=Dr$(I)+Chr$(Val(Mid$(B$,K,3)))
							K=K+2
						Endif
					Endif
				Next K
			Endif
		Endif
	Next I 
	Eflag=0 
Return
'
'
Procedure Do_scan 
	@Rahmung(0)
	Urbild$=Space$(Int((W(34)*W(35)+D/2))
	Local A,B,X,Y,Z%,A$
	Lprint Dr$(27);
	Z%=0
	For Y=0 To (W(35)-1)
		For X=0 To (W(34)-1)
			A=B
			@Delay(W(31))
			B=Peek(Int(W(23)))
			Lprint Dr$(28)
			If Z%>=1 
				Z%=0
				Mid$(Urbild$,(Y*W(34)+X)/2)=Chr$((A+B*16) And 255)
			Else 
				Inc Z%
			Endif
			@Putpix(X*2,Y*2,2,2,B*16)
			A$=Inkey$
			Exit If A$=Chr$(27)
		Next X 
		Lprint Dr$ (29)
		@Delay(W(32))
		Exit If A$=Chr$(27)
	Next Y
	Lprint Dr$(30)
	@Rahmung(1)
Return
'
'
Procedure Putpix(X,Y,Dx,Dy,H)
	Deffill 1,Muster$(Wert%(H))
	Pbox X,Y,X+Dx-1,Y+Dy-1
Return
'
' bewertet die FĂŒllmuster nach Helligkeit und erzeugt Wert%()

Procedure Full_lut
	Local H, A, Byte, Bit,M, A$
	For A=0 To 256 
		Wert%(A)=300 
	Next A
	For M=0 To 32
		Exit If Muster$ (M) =""
		H=0
		For Byte=1 To 32
			A=Asc(Mid$(Muster$(M),Byte,1))
			A$=Right$("00000000"+Bin$(A),8)
			For Bit=1 To 8
				If Mid$(A$, Bit, 1) ="0"
					H=H+1 
				Endif 
			Next Bit 
		Next Byte 
		Wert%(H)=M 
	Next M 
	Repeat 
		A=1
		For H=1 To 255
			If Wert%(H)=300 And Wert%(H+1)<>300 
				Wert%(H)=Wert%(H+1)
				A=0
			Endif
			If Wert%(H)=300 And Wert%(H-1)<>300 
				Wert%(H)=Wert%(H-1)
				A=0 
				Inc H 
			Endif 
		Next H 
	Until A=1 
Return
'
'
Procedure All
	Alert 2,"Ist der Drucker bereit|und die Anpassung gemacht ?",2,"Abbruch|Start",Erg
Return
'
'
Procedure Disl
	Print At(30,11);" ********************";
	Print At(30,12);" *** Bitte warten ***"
	Print At(30,13);" ********************";
Return
'
'
'_______________________________
' Ab hier kommen Lader fĂŒr div Feld-Variablen
'-------------------------------
'
' liest menu in Rollo$()
Procedure Men_init 
	Dim Rollo$(67)
	For I=0 To 65 
		Read Rollo$(I)
		Exit If Rollo$(I)="***"
	Next I
	Let Rollo$(I)=""
	Let Rollo$(I+1)=""
Return 
' menu text
Data Desk, About SCANNER
Data -------------
Data acc1,acc2,acc3,acc4,acc5,acc6,""
Data   I/O   ,-lade------------, Druckertreiber , Ur-Bild ,-speichere--
Data Druckertreiber, Ur-Bild, Bild (BIN), Bild(NEO), Bild(P01)
Data ------------, Hardcopy,----------, Joyst.-Peek,""
Data Abtastung	,-Druckertreiber--, Initialisierung, Horiz.-Vorschub
Data Vert .-Vorsch;CR , Abschlu_, Timer Horizontal, Timer Vertikal, -Schrittzahl--, Horizontal, Vertikal,""
Data Aufber., Zoom,-USM---------, breit, schmahl,-Gradation-, Licht, Mittelton, Schatten 
Data -Grundwerte-, Licht, Schatten,""
Data Starte, Aufbereitung , Abtastung,""
Data   Sonstiges,-zeige-----, Parameter, Bild,------, Ende ,""
Data ***
'
' liest FĂŒllmuster in Muster$()
Procedure Full_init 
	Dim Muster$(32)
	Dim Zeil$(15)
	Local A$,V,N,Z 
	For N=0 To 32 
		Read A$
		Exit If A$="***"
		For V=0 To 15 
			Read A$
			Exit If A$="*"
			Repeat
				A$=A$+A$
			Until Len (A$)>=16 
			Zeil$(V)=Left$(A$,16)
		Next V
		For Z=V To 15
			Zeil$ (Z) =Zeil$ (Z-V)
		Next Z
		Muster$(N)=""
		For Z=0 To 15
			Muster$(N)=Muster$(N)+Mki$(Int(Val("&X"+Zeil$(Z))))
		Next Z 
	Next N 
Return

' Hier beginnen die FĂŒllmuster-Daten 
Data **
Data 0 
Data *,*
Data 0100 
Data 0 
Data 0001 
Data 0 
Data *,*
Data 0100 
Data 0001 
Data *,*
Data 0101 
Data 0010 
Data 1010 
Data 0100 
Data *,*
Data 01 
Data 10 
Data *,*
Data 0101 
Data 1101 
Data 1010 
Data 1011 
Data *,*
Data 0111 
Data 1101 
Data *,*
Data 0111 
Data 1111 
Data 1101 
Data 1111 
Data *,*
Data 1 
Data *,***
'
'
' zeigt wo und welche menu-EintrÀge angezeigt werden 
Procedure Anz_init 
	Dim Anz%(1,65)
	Local X,Y,A 
	For A=0 To 65 
		Anz%(0,A)=0 
		Anz%(1,A)=0 
	Next A 
	Do
		Read A
		Exit If A=999 
		Read X,Y 
		Anz%(0,A)=X 
		Anz%(1,A)=Y 
	Loop 
Return

Data 23,40,22, 26,30,3, 27,1,4,28,1,5,29,1,6,30,1,7
Data 31,1,9,32,40,9,33,1,12,34,1,13,35,1,14,39,40,12
Data 40,40,13,41,40,14, 42,1,17,43,1,18,44,1,19,45,1,20
Data 46,40,17,47,40,18, 48,40,19,999
'
'
' _____________________________
' Ab hier kommen allgemeine Proceduren 
' _____________________________
'
'
Procedure Textedit(X,Y,Lmax,A$, Z)
	Local B$,L,P,B,C 
	L=Len(A$)
	P=L+1
	Do
		Print At(X,Y);A$;" "
		Print Chr$(27);"p";
		If L>0 And P<=L
			Print At (X+P-l, Y); Mid$(A$,P, 1);
			Print Chr${21); "q" ;
		Else
			Print At(X+P-l,Y)
			Print Chr$(27) ;"q";
			Print At (X+P, Y)
		Endif
		C=Bios (2,2)
		B=C And 255 
		B$=Chr$(B)
		C=C/&H10000 And 255 
		Exit If B=13 Or B=27 
		If B=127 And L>0 And P<=L
			A$=Left$(A$, P-1)+Right$(A$,L-P)
			L=Len(A$)
		Endif
		If B=8 And P>1 And L>0
			A$=Left$(A$, P-2)+Right$(A$,L-P+1)
			L=Len(A$)
			Dec P 
		Endif
		If C=75 And P>1 
			Dec P
		Endif
		If C=77 And P<=L 
			Inc P 
		Endif 
		If B=9 
			P=L+1 
		Endif
		If ((B>31 And B<>127 And Z<>-1) Or (B>44 And B<58 And B<>47 And Z=-1)) And Lmax>L 
			If L>=P
				A$=Left$(A$,P-l)+B$+Right$(A$,L-P+1)
			Else
				A$=A$+B$
			Endif 
			L=Len(A$)
			Inc P 
		Endif 
	Loop
	Print At (X,Y);A$;" ";
	Rueck$=A$
Return
'
' leere Procedur 
Procedure N 
Return
'
'
Procedure Fehler
	Local Du 
	If Eflag=0
		Alert 3,"Fehler Nr.:"+Str$(Err)+"|	|	",1,"OK",Du
		Close 
	Else
		Alert 3,"Fehler im Druckertreiber|oder in Korrekturdaten| ",1,"OK",Du
	Endif
	Eflag=0
	Cls
	Menu Rollo$()
	Resume Start 
Return
'
'
Procedure Rahmung(A)
	Dpoke Intin,A 
	Vdisys 104 
Return
'
'
Procedure Delay(A)
	Pause A 
Return