Millimetripaperin luku

Description in (some kind of) English

With this system you can move graphs from paper to files of (X,Y) pairs.

  1. Set the paper on a scanner and a graphics file of any kind.
  2. With Corel Draw or some other graphics tool open the graphics file
  3. Make a color separation and make everything else white but the graph
  4. Print the graph to a Postscript file ( " graph.ps " )
  5. Give the Postscript file to this program ( " PS2PX5 graph.ps" )
  6. You get a new file which contains the (X,Y) pairs ( " graph.txt " )

You can use this program many ways:

  1. In MSDOS 3.1 - MSDOS 7.0 or Windows command line
    • As a parameter
    • interactively
  2. In Windows you can drag and drop the graph file on the icon of this program.
  3. You can write a sript and give the name as a parameter
There is the source code ( PS2XY5.BAS ) which is written with QuickBasic 4.5. If you make changes to it, please tell me.
There is also the compiled version ( PS2XY5.EXE )

DOWNLOAD COMPILED EXE-FILE

Taustaa:
Kari Loikas etsi ohjelmaa, jolla millimetripaperille tulostettu kuva voitaisiin lukea tietokoneelle edelleen ohjelmallisesti käsiteltäväksi. Löysimme seuraavan ratkaisun:
-Kuva scannataan normaalilla tasoscannerilla
-Kuvasta häivytetään asteikkoviivoitus värierottelulla jollain piirto-ohjelmalla
-Kuva tulostetaan Postscript-tiedostoksi. Itse käytimme tähän Apple 16/600 PS -kirjoittimen ajureita Windows 2000:ssa.
-Kirjoitetaan ohjelma, joka poimii PS-tiedostosta varsinaisen kuvan esille ja tallettaa sen X/Y-koordinaatteina uuteen tiedostoon.
Karin kirjoittama ohje PDF-tiedostona sisältää kaiken oleellisen asiasta.

Kari ei ehtinyt ohjelman kirjoittamiseen, ja minullakin oli kiire, joten otin ensimmäisen käsiin sattuneen ohjelmointiympäristön ja tein ohjelman. Valitettavasti käytössä oli QuickBasic 4.5, joten siitä nyt vaan tuli DOS-ohjelma. Ainoa haitta asiasta on se, että ohjelma käynnistää DOS-ikkunan ja pyörii siellä. Myöskään CUT and PASTE -tempuille ei haaskattu hetkeäkään mietintäaikaa.
(Eikös muuten Basicilla tulekin kamalaa spagettikoodia ;) Tietenkään asia ei ollut vielä tällä selvä, joten jouduimme kirjoittamaan ohjelmasta uuden version. Liitän sen tämän ensimmäisen perään.

Ohessa on ohjelmien sorsakoodit vailla enempiä kommentteja niille, joita asia kiinnostaa.

Ykkössversio: (plot.bas)

CLS
'versio 1.0
PRINT "Ohjelma lukee Postscript-tiedostoa ja tulostaa pisteit„ kuvaruudulle"
PRINT "sek„ tiedostoon"

INPUT "Anna dev:\hak\INfile.jat"; innimi$
INPUT "Anna dev:\hak\OUTfile.jat"; outnimi$

OPEN innimi$ FOR INPUT AS #1
OPEN outnimi$ FOR OUTPUT AS #2

DO
   LINE INPUT #1, m$
LOOP UNTIL m$ = "end reinitialize"

PRINT : PRINT "----"
      DO: LOOP UNTIL INKEY$ > ""

SCREEN 11
LINE (1, 1)-(639, 479), , B
kx = .05
ky = .05
DO
   k$ = INPUT$(1, 1)
  
   IF k$ <> "I" AND k$ <> "M" AND k$ <> "N" THEN EXIT DO
  
   INPUT #1, l1   'X-koord
   PRINT #2, l1;
  
   INPUT #1, l2   'Y-koord
   PRINT #2, l2
  
   PSET (l1 * kx, l2 * ky)
LOOP UNTIL loppu

PRINT : PRINT "LOPPU"

CLOSE



Kakkosversio: (PS2XY.BAS)

LISÄYS 251002 PTM: Tottakai Kari, kuten minäkin, unohti, millä ohjelmalla tuo alkuperäinen kuvankäsittely oli tehty, joten seuraavalla kerralla homma tehtiin CorelDraw 10 :llä digikameralla tehdystä kuvasta. Tietenkään PS-koodi ei ole mitään sukua aiemmalle, joten kirjoitin toisen ohjelman.
Tästäkin jouduttiin tekemään useita kokeiluja, koska Corel ei kahdella peräkkäisellä kerralla suostunut tekemmän samanlaista koodia. Ohjausmerkit poikkesivat toisistaan. Lopulta löydettiin rakenne, joka toimi kaikilla Corellin antamilla PS-tiedostoilla.

Kuten sorsasta näkyy, sen miettimiseen ei käytetty kuin n. 0.1 sek HPU (Head Prosessing unit) -aikaa. Ratkaisu perustuu Brute Force -menetelmään, joten se toimii varmasti.

CLS
'versio 2.0
PRINT
PRINT "Ohjelma lukee Postscript-tiedostoa ja tulostaa pisteita 
kuvaruudulle"
PRINT "seka lukuarvot tiedostoon"

INPUT "Anna dev:\hak\INfile.jat"; innimi$
INPUT "Anna dev:\hak\OUTfile.jat"; outnimi$
tmpnimi$ = "c:\zfksdjh.tmp"
PRINT "Kuvasta paaset painamalla jotain nappainta, kuten nytkin"
PRINT "Ohjelma tekee tilapaistiedoston '"; tmpnimi$; "' ja tuhoaa sen"
a$ = "\": B$ = "/"
DO
   LOCATE 1, 1: PRINT a$: SWAP a$, B$
LOOP UNTIL INKEY$ > ""

OPEN innimi$ FOR INPUT AS #1
OPEN tmpnimi$ FOR OUTPUT AS #2

DO

   DO
      'm$ = INPUT$(1, 1)
     
      LINE INPUT #1, m$
   LOOP UNTIL m$ = "/$fm 0 def" OR EOF(1)
   IF EOF(1) THEN EXIT DO
     
CLS
   n = 0
   DO
         m$ = INPUT$(1, 1)
         IF INSTR("1234567890 ." + CHR$(13), m$) > 0 THEN
            IF INSTR(" " + CHR$(13), m$) THEN n = n + 1 ELSE n = 0
            IF n < 3 THEN
               PRINT #2, m$;
            END IF
         END IF
  
   LOOP UNTIL m$ = "S"

LOOP UNTIL EOF(1)

CLOSE
'----
'Toinen kierros lukee siivotun ja tallettaa (x,y)-pareina


OPEN tmpnimi$ FOR INPUT AS #1
OPEN outnimi$ FOR OUTPUT AS #2
maxx = 640
maxy = 480
DO
   INPUT #1, x
   INPUT #1, Y
   PRINT #2, x, Y
   IF x > maxx THEN maxx = x
   IF Y > maxy THEN maxy = Y
LOOP UNTIL EOF(1)
CLOSE

cmd$ = "DEL " + tmpnimi$
SHELL cmd$


'----
'kolmas kierros piirtaa kuvan
'skaalataan sen verran (0.95x) ett„ pisteet mahtuvat ruudulle
kx = 640 / maxx * .95
ky = 480 / maxy * .95

OPEN outnimi$ FOR INPUT AS #1
SCREEN 11
LINE (1, 1)-(639, 479), , B

LOCATE 1, 1
DO
   INPUT #1, x
   INPUT #1, Y
   x = x * kx
   Y = Y * ky
   PSET (x, Y)
LOOP UNTIL EOF(1)
CLOSE

DO
LOCATE 1, 1: PRINT a$: SWAP a$, B$
LOOP UNTIL INKEY$ > ""


Kolmosversio (PS2XY5.BAS)

MUUTOS 171008 PTM: Teitpä sen miten tahansa, se joka tapauksessa ryömii yöllä esiin kolostaan ja asettuu jalkasi alle, kun olet pimeydessä kömpimässä kotiin. EIkö vaan tästäkin ohjelmasta taas löydetty bugi. Jostain hiiskatin syystä joku graafinen ohjelma pläjäyttää keskelle tiedostoa merkkejä, joita luulin loppumerkeiksi. Piti tehdä tämän huomioiva korjaus. Samassa yhteydessä havaittiin, että ohjelman grafiikkaosa toimii yhdessä, muttta ei toisessa koneessa. Sekin piti korjata.

Grafiikka käännettiin saman tien nurin, eli oikein päin ja skaalattiin uudestaan.
Niin kova touhu, kuin grafiikan kanssa tehtiinkin, pistettiin siihen saman tien kytkin, jolla sen saa pois päältä.

Kun nyt kerran korjailemaan alettiin, tehtiin samalla muunnos, joka sallii ohjelman käyttämisen työjonossa, eli hienosti sanoen eräajossa.
Eräajossa ei tietenkään piirrellä kuvia

Ohjelman kutsun voi nyt kirjoittaa eräajojonoon, eli DOS:n BAT -tiedostoon ja sen perään voi pistää käsiteltävän tiedoston nimen. Kun nyt näitä rivejä tekee yhden kutakin käsiteltävää tiedostoa kohden, saa monta tiedostoa käsiteltyä yhdellä kerralla.

Hiiren käyttöön tottuneita on ajateltu siten, että kun avataan hakemisto, jossa on käsiteltäviä kuvatiedostoja, voidaan tiedostot yksi kerrallaan nostaa ohjelman ikonin päälle. Ohjelma käsittelee tiedoston ja tulostaa samaan hakemistoon, jossa lähdetiedosto oli.

DOWNLOAD COMPILED EXE-FILE

PRINT "--------PS2PX v5.0, Ajo: "; TIME$; "-----------------"
param$ = COMMAND$

PRINT
IF param$ = "" THEN
   PRINT "Ohjelma lukee Postscript-tiedostoa ja tulostaa pisteit„ kuvaruudulle"
   PRINT "sek„ tiedostoon"
   PRINT " http://users.utu.fi/ptmusta/plot.shtml"
   PRINT
   PRINT "Jos annat k„sitelt„v„n tiedoston nimen komentorivill„, "
   PRINT "tulostiedoston nimi saa jatkeen TXT"
   PRINT "T„ll”in ei piirret„ kuvaa"
   PRINT "( Voit raahata windowsissa l„hdetiedoston ohjelman ikonin p„„lle)"
   PRINT "Jos k„sitelt„v„ tiedosto on samassa hakemistossa,";
   PRINT " kuin t„m„ ohjelma, ei tarvitse antaa polkua tiedoston nimess„"
  
   INPUT "Anna [[dev:]\hak\]INfile.jat"; innimi$
   INPUT "Anna [[dev:]\hak\]OUTfile.jat"; outnimi$
   kuva$ = "E"
   INPUT "Piirret„„nk” kuva "; kuva$
ELSE
   kuva$ = "E"
   innimi$ = param$
   p = INSTR(param$, ".")
   outnimi$ = LEFT$(param$, p) + "txt"
   PRINT "Luetaan tiedostosta "; param$
   PRINT "Talletetaan tiedostoon"; outnimi$
END IF

OPEN innimi$ FOR INPUT AS #1
OPEN outnimi$ FOR OUTPUT AS #2

maxx = 640
maxy = 480

n = 0' pisteiden laskuri
'---------
   'Alusta roskat pois
   DO
      LINE INPUT #1, M$
   LOOP UNTIL M$ = "/$fm 0 def" OR EOF(1)
   IF EOF(1) THEN END
'---------
   'Luetaan varsinainen taulukko
   DO
      LINE INPUT #1, r$
      
      l$ = UCASE$(RIGHT$(r$, 1))
      
      'Rivin loppumerkkin„ on 'L' tai 'm' ainakin t„ss„ tapauksessa
      IF (l$ = "M") OR (l$ = "L") THEN
  
         'X on rivin alussa merkkijonona, muutetaan luvuksi
         x = VAL(r$)
         x$ = STR$(x)
         'Y rivin keskell„, muutetaan luvuksi
         y = VAL(RIGHT$(r$, LEN(r$) - INSTR(r$, " ")))
         
         IF x > maxx THEN maxx = x
         IF y > maxy THEN maxy = y
        
         PRINT #2, x, y
         n = n + 1
     
      END IF


   LOOP UNTIL (INSTR(r$, "%%") > 0) OR (EOF(1))

CLOSE

IF UCASE$(kuva$) <> "E" THEN
   '-------------
   'Toinen kierros piirt„„ kuvan
   'skaalataan sen verran (0.95x) ett„ pisteet mahtuvat ruudulle
   kx = 640 / maxx * .95
   ky = 480 / maxy * .95

   OPEN outnimi$ FOR INPUT AS #1
   SCREEN 11
   LINE (1, 1)-(639, 479), , B

   FOR i = 1 TO n
      INPUT #1, x
      INPUT #1, y
      x = x * kx
      y = 480 - y * ky
      PSET (x, y)
   NEXT
   CLOSE


   LOCATE 1, 1: PRINT "Press any key"
   DO: LOOP UNTIL INKEY$ > ""

END IF


On aika turha koittaa kysellä lisäohjeita. Itsekin aiomme aktiivisesti unohtaa koko jutun mahdollisimman pian. Jos kuitenkin kaikesta huolimatta saat jutun toimimaan, ilmoittele meille. Lähtetämme sitten pankkitilin numeron ;)
Ilmoittele silti, vaikket osaisikaan suorittaa rahansiirtoa pankkitilille. Olemme uteliaita näkemään, onko joku keksinyt tälle jotain käyttöä.
PTMUSTA at UTU.FI