← ST-Computer 08 / 1988

Eigene Bilder in der Resource

Programmierpraxis

Bilder verschönern eines Jeden Dialogbox. Doch was tun, wenn das Lieblings-RCS selbige stiefmĂŒtterlich behandelt? Ganz einfach: Die Bilder mit einem Malprogramm malen und eine Resource draus machen. RCS von Digital Research kann Bilder (Bitblk-Strukturen) nur hinzu laden und erwartet dabei einen C-Quellcode. Das RCS von Kuma besitzt zwar einen eigenen Icon-Editor, doch oft genug hat man das Bild schon und will es nicht noch einmal abmalen.

Außerdem soll es ja auch Leute geben, die mit der Lupe ihres Malprogramms besser zurechtkommen als mit einem Icon-Editor. So kam mir die Idee, ein Programm zu schreiben, daß einen beliebigen Bildschirmausschnitt in eine Bitblk-Struktur ĂŒbersetzt. Besitzer des Kuma-RCS können so auch den Icon-Editor entlasten, denn ihr RCS ermöglicht es bequem, Bitblk-Strukturen in Icon-Strukturen zu wandeln. Sie können sich also fortan die Bilder fĂŒr Ihre Resource mit Ihrem Lieblings- Malprogramm malen. Das GFA-Programm, das die Konvertierung vornimmt, finden Sie im nebenstehenden Listing.

Zur Vorgehens weise des Programms: ZunĂ€chst wĂ€hlen Sie ein Bild aus, aus dem Sie den Ausschnitt haben wollen. Dieses muß im Screenformat (32kB) vorliegen. Dann können Sie mit einer ‘Gummibandbox’ den gewĂŒnschten Ausschnitt markieren. Dieser wird im String ‘ Aus$’ gespeichert und dann in die Bitblk-Struktur umgewandelt.

Diese wird in eine komplette Resource eingelagert, die mit jedem RCS zu laden ist. Zur Erzeugung der Bitblk-Struktur mĂŒssen allerdings zunĂ€chst Höhe und Breite des Ausschnitts bekannt sein. Jeder String, in dem per ‘GET’ ein Bildschirmteil gespeichert wurde, besitzt einen sechs Bytes langen Vorspann, in dem im ersten Wort die Breite und im zweiten die Höhe (jeweils in Pixeln) des Ausschnitts vermerkt sind. Das dritte Wort enthĂ€lt Informationen ĂŒber die Bildschirmauflösung, Farbebenen etc.

Jede neue Pixelzeile des Ausschnitts beginnt an einer Wortadresse. Das bedeutet, daß bei einem 15 Pixel breiten Ausschnitt also jeweils das letzte Bit der Wörter ‘verschenkt’ wird. WĂ€re dieser Ausschnitt wiederum 15 Pixel hoch, so ergĂ€be sich fĂŒr die LĂ€nge des Strings in dem er gespeichert ist:

6+15*2 = 36 Bytes

Der String wĂ€re wegen der WortlĂ€nge jeder Zeile genauso lang, wenn der Ausschnitt nur ein Pixel breit wĂ€re. Leider gibt es bei diesen Werten, die man aus dem Vorspann erfahren kann, einige Ungereimtheiten. Ein 16 Pixel breiter Ausschnitt nimmt nicht - wie vermutet -pro Zeile zwei Byte in Anspruch, sondern vier. Also wird bei jedem 16. Pixel bereits ein neues Wort begonnen. Ein Ausschnitt, fĂŒr den im Vorspann eine Höhe von Null Pixeln vermerkt ist, ist aber in Wirklichkeit ein Pixel hoch. Daraus entstehen die zunĂ€chst unlogisch wirkenden Berechnungen im Programm. In der Bitblk-Struktur speichert (und erwartet, logo!) das AES folgende Informationen (siehe Tabelle) womit wir auf eine LĂ€nge von 14 Bytes kommen. Hinzu kommen die Bilddaten: pro angefangenem Wort 2 Bytes oder viel einfacher, LĂ€nge von ‘Aus$’-6.

Nun macht ja ein Bitblk noch keine Resource. Wir brauchen noch einen sog. Resource-Header, der wiederum 36 Bytes lang wird (Genaueres siehe Listing).

Dann fehlt noch die Objekt-Struktur (24 Bytes) und die Objektbaumtabelle (bei einem Baum 4 Bytes). Das wĂ€r’s eigentlich schon, doch kann das RCS von Digital Research mit der Resource, die jetzt entstĂŒnde, herzlich wenig anfangen. Das liegt daran, daß der Bitblk in dieser Resource eine Vaterfigur spielte, also das Wurzelobjekt seines Baumes darstellte.

Leider erlaubt eben dieses RCS nicht, ein solches Objekt auf das Klemmbrett zu kopieren, um es von dort aus weiter zu verarbeiten. Wir kommen also nicht umhin, dem Bild(chen) ein Vaterobjekt ĂŒberzuordnen. Aber das soll ja kein Problem sein. Ich habe eine geringfĂŒgig grĂ¶ĂŸere Box gewĂ€hlt, in der sich das Bild dann befinden wird. Allerdings erfordert das eine weitere Objektstruktur, mithin wird die Resource nochmal 24 Bytes lĂ€nger. Die LĂ€nge ist wichtig fĂŒr den Eintrag 'Rssize’ im Resource-Header (das ist der letzte). Haben Sie mitgezĂ€hlt? FĂŒr die LĂ€nge ergibt sich:

36 Bytes (Header)

  • Len(Aus$)-6 Bytes (Bilddaten)
  • 14 Bytes (Bitblk)
  • 2*24 Bytes (Objekte)
  • 4 Bytes (Objektbaumtabelle)

Es wird nun ein String dieser LĂ€nge vorbereitet und von seiner Adresse an werden die Daten per POKE, DPOKE und LPOKE gesetzt. Anschließend wird dieser String unter dem von Ihnen gewĂ€hlten Dateinamen gespeichert.

Eine kleine Bemerkung vielleicht noch zu den letzten vier Werten der Objektstruktur. Hier sind X- und Y-Position (relativ zum Vaterobjekt) sowie Breite und Höhe der Objekte vermerkt. WĂ€hrend in einer Resource, die mit der AES-Funktion 110 (RSRC_LOAD) geladen wurde, diese Werte in Pixelkoordinaten vermerkt sind, werden sie in der Resource-Datei in Zeichenkoordinaten verlangt. Auf dem Monochrommonitor ist das ein Raster von 16 Pixeln Höhe und 8 Pixeln Breite. Der entsprechend geteilte Wert wird im Low-Byte der jeweiligen Koordinaten-Wörter gespeichert. Sollte die Koordinate nun nicht exakt auf diesem Raster liegen, also ein Rest bleiben, so wird dieser (nun in Pixeln) im High-Byte vermerkt. Beim Laden werden die Werte entsprechend der Bildschirmauflösung umgerechnet. Wenn Sie also das Programm in der mittleren Auflösung verwenden wollen, mĂŒssen Sie in der Zeile, in der die Koordinate durch 16 geteilt wird, diese 16 durch eine 8 ersetzen.

Ich hoffe, daß alle anderen Fragen durch das Listing selbst zu beantworten sind. Als dann wĂŒnsche ich Ihnen viel Spaß - beim Malen!

bi_pdata (Zeiger auf Bilddaten) 4 Bytes bi_wb (Breite in Bytes) 2 Bytes bi_hl (Höhe in Pixeln) 2 Bytes bi_x (X-Position) 2 Bytes bi_y (y-Position) 2 Bytes bi_color (Farbe des Bildes) 2 Bytes

Tabelle der Bild-Struktur

' ***************************************************************** ' * PIC_BITB.BAS - aus (Bildschirm-) Bildern Bitblöcke erstellen * ' * Copyright 1988 Ingo BrĂŒmmer, Lutherstraße 60, 3000 Hannover 1 * ' ***************************************************************** ' Repeat Print " Bitte eine Bilddatei wĂ€hlen: " Fileselect Chr$(Gemdos(25)+65)+"\*.*","",Bild$ ' If Bild$="" ! Bei Abbruch Edit ! Ende Endif Bload Bild$,Xbios(2) ! Bild laden Repeat Aus$="" Defmouse 5 ! Maus -> Kreuz Sget Moni$ ! Bildschirm merken Repeat Until Mousek=1 ! Warten auf linke Taste X1%=Mousex ! Koordinaten merken Y1%=Mousey Do Mouse X2%,Y2%,T% ! Maus merken Box X1%,Y1%,X2%,Y2% ! Gummibox zeichnen Vsync ! Mit Vertical-Interrupt synchronisieren Sput Moni$ ! altes Bild drauf Exit If T%=0 ! Raus, wenn Maus losgelassen Loop Get X1%,Y1%,X2%,Y2%,Aus$ ! Bildchen ausschneiden Defmouse 0 ' Put X1%,Y1%,Aus$,12 ! Und invertiert drauflegen Pause 25 Alert 0,"Bitblk draus machen?",1,"Ja|Nein",D% If D%=1 Fileselect Chr$(Gemdos(25)+65)+"\*.*","", Rs$ Endif If D%=1 And Rs$<>"" ! Wenn Speichern und nicht Abbruch: ' B%=Dpeek(Varptr(Aus$)) ! Breite in Pixeln B%=(B% Div 16+1)*16 ! auf WortlĂ€nge bringen H%=Dpeek(Varptr(Aus$)+2)+1 ! Höhe in Pixeln ' Imd$=Right$(Aus$,Len(Aus$)-6) ! Bilddaten ' Rsc$=Space$(36+Len(Imd$)+14+2*24+4) ! Platz fĂŒr RSC schaffen Adr%=Varptr(Rsc$) ' *************** rshdr basteln *************** Dpoke Adr%+0,1 ! Vrsn, immer(?)=1 Dpoke Adr%+2,36+Len(Imd$)+14 ! Offset Objekt-Struktur Dpoke Adr%+4,36+Len(Imd$)+14 ! Offset Tedinfo-Struktur Dpoke Adr%+6,36+Len(Imd$)+14 ! Offset Iconblk-Strukur Dpoke Adr%+8,36+Len(Imd$) ! Offset Bitblk-Struktur Dpoke Adr%+10,36+Len(Imd$) ! Offset freie Strings Dpoke Adr%+12,36 ! Offset gebundene Strings Dpoke Adr%+14,36 ! Offset Image-Daten Dpoke Adr%+l6,36+Len(Imd$)+14 ! Offset freie Images Dpoke Adr%+18,36+Len(Imd$)+14+2*24 ! Offset Baumtabelle Dpoke Adr%+20,2 ! Anzahl der Objekte Dpoke Adr%+22,1 ! Anzahl der BĂ€ume Dpoke Adr%+24,0 ! Anzahl der Tedinfos Dpoke Adr%+26,0 ! Anzahl der Iconblöcke Dpoke Adr%+28,1 ! Anzahl der Bitblöcke Dpoke Adr%+30,0 ! Anzahl der Strings Dpoke Adr%+32,0 ! Anzahl der Images Dpoke Adr%+34,Len(Rsc$) ! LĂ€nge der Resource ' ' **************** Bilddaten eintragen ********* Bmove Varptr(Imd$),Adr%+36,Len(Imd$) ' ' ************* Bit Image Block basteln ******** Add Adr%,36+Len(Imd$) ! Anfangsadresse d.Bitblk Lpoke Adr%,36 ! Adresse der Bilddaten Dpoke Adr%+4,B% Div 8 ! Breite in Bytes Dpoke Adr%+6,H% ! Höhe in Pixeln Dpoke Adr%+8,0 ! X-Position Dpoke Adr%+10,0 ! Y-Position Dpoke Adr%+12,1 ! Farbe Add Adr%,14 ! Anfangsadresse der Objektstruktur ' ' ********* Objektstruktur der Vater-Box ******* Dpoke Adr%,-1 ! NĂ€chstes Objekt, hier: keines Dpoke Adr%+2,1 ! Erstes Kind, hier: Nr.1 Dpoke Adr%+4,1 ! Letztes Kind, hier: Nr.1 Dpoke Adr% + 6,20 ! Objekttyp - G_box Dpoke Adr%+8,0 ! Objektflag Dpoke Adr%+10,16 ! Objektstatus - Outlined Lpoke Adr%+12,135424 ! Obj_spec - Langwort Dpoke Adr%+16,0 ! X-Position Dpoke Adr%+18,0 ! Y-Position Dpoke Adr%+20,B% Div 8+1 ! Breite in Spalten Poke Adr%+22,0 ! (Rest-)Höhe in Pixeln im Highbyte Poke Adr%+23,H% Div 16+1 ! Höhe in Zeilen im Lowbyte Add Adr%,24 ' ' ********* Objektstruktur des Bitblk ********** Dpoke Adr%,0 ! NĂ€chstes Objekt, hier: Vater Dpoke Adr%+2,-1 ! Erstes Kind, hier: keines Dpoke Adr%+4,-1 ! Letztes Kind, hier: keines Dpoke Adr%+6,23 ! Objekttyp - Bitblk Dpoke Adr%+8,32 ! Objektflag - Lastob Dpoke Adr%+10,0 ! Objektstatus Lpoke Adr%+12,36+Len(Imd$) ! Zeiger auf Bitblk - Langwort Dpoke Adr%+16,0 ! X-Position Dpoke Adr%+18,0 ! Y-Position Dpoke Adr%+20,B% Div 8 ! Breite in Spalten Poke Adr%+22,H% Mod 16 ! (Rest-)Höhe in Pixeln im Highbyte Poke Adr%+23,H% Div 16 ! Höhe in Zeilen im Lowbyte ' ' ************ Objektindex - Tabelle ************ Lpoke Adr%+24,36+Len(Imd$)+14 ! Objektanfang des 0.Baumes Bsave Rs$,Varptr(Rsc$),Len(Rsc$) ! Speichern Endif Put X1%,Y1%,Aus$ ! Invertierung weg Alert 0," Nochmal oder neues Bild? ",1,"Nochmal|Neu|Ende",D% Until D%>1 Until D%=3

Mit diesem Listing können sie ihr Resource einbinden

Bild 1: Bilder sagen mehr als tausend schöne Worte
Ingo BrĂŒmmer