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)
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