Text als Grafik auslesen
-
Diese Idee hatte ich schon verworfen, da es mir zu aufwendig ist

Ich hatte es mal vor etlichen Jahren mit kyrillischen Zeichen in Pascal und VESA-Grafik realisiert. Aber ich komme vom Thema ab
Prinipiell will ich es ja schon so machen, jedoch will ich mir die Tabellen nicht von Hand erstellen, sondern ich will mir einfach intern eine Grafik erzeugen. In diese Grafik schreibe ich dann den Text und übertrage dann die Pixel auf mein Display.
DirectX sollte alle benötigten Funktionen haben.
-
Da brauchst du bestimmt kein DirectX für, die WinAPI tut's auch.
Mit CreateDC() kannst du eine Zeichenfläche erstellen, mit TextOut() einen beliebigen Text darauf zeichnen lassen. GetPixel() ist eine Möglichkeit, die Grafik pixelweise auszulesen. Schau dir dazu einfach mal den Grafik-Bereich in der Win32-Referenz genauer an.
-
Hört sich gut an.
Ich melde mich dann später mit den Ergebnissen
-
habe mir folgendes ausgekaspert :
HDC hdcScreen; hdcScreen = CreateDC((LPCWSTR)"Display", NULL, NULL, NULL); DWORD d=GetLastError(); TextOut(hdcScreen,0,0,(LPCWSTR)"Hallo",5); COLORREF c; for (int x=0;x<MaxX;x++) { for (int y=0;y<MaxY;y++) { c=GetPixel(hdcScreen,x,y); if (c>0) SetPoint(x,y); } } DeleteDC(hdcScreen);ich bekomme jedoch bei der Funktion CreateDC den GetLastError 8, welche bedeutet, dass nicht genug Speicher zur Verfügung steht.
Was ist mein Fehler?
-
Also, bei mir funktioniert dein Beispiel wunderbar (außer dass ich mir die Wchar-Konvertierung von "Display" gespart habe).
Ich habe dir aber trotzdem Unsinn erzählt, weil das ganze gibt den Text auf dem Bildschirm aus, was wahrscheinlich nicht beabsichtigt ist.
Stattdessen solltest du die Kombination CreateCompatibleDC(), CreateBitmap() und SelectObject() verwenden, dann findet die Textausgabe ausschließlich im Speicher statt.
-
Kann leider erst morgen weiter dran rumforschen.
CreateBitmap() hört sich ja für mich ganz passend an. Ma guggen.
-
Hallo,
vielleicht ist ja auch dieses Tutorial was für dich. Da wird u. a. erklärt wie man den Zeichensatz einer Schriftart in einer Bitmap unterbringt.
-
das Tutorial war gut

Habe mir nun diese Funktion zurechtgebastelt und stelle sie damit auch zur Diskussion :bool WriteText(String ^ s) { bool ret=false; HDC hdc; hdc=CreateCompatibleDC(NULL); HBITMAP hbm=CreateCompatibleBitmap(hdc,MaxX,MaxY); SetMapMode( hdc, MM_TEXT ); HFONT font = CreateFont( 16, // Höhe der Font 0, 0, 0, 1, false, false, false, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, ANTIALIASED_QUALITY, VARIABLE_PITCH, (LPCWSTR)"Arial" ); // Fontname SelectObject( hdc, hbm ); SelectObject( hdc, font ); SetTextColor( hdc, RGB(255,255,255) ); SetBkColor ( hdc, 0x00000000 ); SetTextAlign( hdc, TA_TOP ); COLORREF c; for (int x=0;x<MaxX;x++) { for (int y=0;y<MaxY;y++) { c=SetPixel(hdc,x,y,RGB(0,0,0)); } } wchar_t buf[100]={0}; for (int i=0;i<s->Length;i++) buf[i]=s[i]; TextOut(hdc,0,0,(LPCWSTR)buf,s->Length); for (int x=0;x<MaxX;x++) { for (int y=0;y<MaxY;y++) { c=GetPixel(hdc,x,y); if (c>0) SetPoint(x,y); //da schreibe ich nun meine Info :) } } DeleteDC(hdc); return ret; }
-
Der Font ist viel zu gross und dann noch proportional für so ein kleines Display. Ich würde das ganz anders machen. Erst schreib ich mir ein Programm, das die Zeichen 32 bis 128 in der Konsole ausgibt. Dann mach ein Screenshot davon (in der Konsole stelle ich mir vorher noch die gewünschte Groesse ein, z.b. 6x8 ) und speicher den als 1 Bit Bild. Das lese ich ein und weil alles im 6x8 Raster liegt, kann ich ganz simpel alles rauskopieren. Effektiv sollte das weniger als 1 Stunde dauern. f'`8k
Gruß, TGGC (\-/ has leading)
-
Auch ne Lösung

Hat auch den Vorteil, dass ich ohne grossen Aufwand weiß wieviele Zeichen in eine Zeile passen. Die Schriftart "Arial monospaced for SAP" sollte im Prinzip dasselbe ermöglichen.
TGGC's Vorschlag ist jedoch performanter
Mal gucken ob ich morgen dafür Zeit hab, heute muss ich leider noch bis 20:00 in der Firma ausharren ...
-
ok, bin nicht mit einer Stunde hingekommen, sondern habe branchenüblich um 50% überzogen

hier nun mein neuer Code :
void ReadTypes() { //das Bild mit den Zeichen hat 176x32 Pixel types = (Byte**)new Byte*[176]; for (int i=0;i<176;i++) { types[i]= new Byte[4]; } for (int x=0;x<176;x++) { for (int y=0;y<4;y++) { types[x][y]=0; } } //die relevanten Informationen stehen ab dem offset 0x3F //begonnen wird mit der letzten Zeile //1 Bytes enthält jeweils 8 Pixel einer Zeile //1 Zeile besteht aus 24 Bytes -> die letzten beiden können überlesen werden FileStream^ file=gcnew FileStream("types.bmp", FileMode::Open);; BinaryReader^ br=gcnew BinaryReader(file); br->ReadBytes(0x3E); for (int y=31;y>=0;y--) { for (int x=0;x<22;x++) { Byte b=br->ReadByte(); int i=0; while (b>0) { if (b%2) { types[x*8+7-i][y/8] |= 1<<(y%8); } b/=2; i++; } } br->ReadBytes(0x02); } }void WriteText2(String^ s) { const char extra_types[]={'(',')','.',',',':',';','/','*','-','+','!','?','$','%','&','=','ß','ö','ä','ü','Ö','Ä','Ü','#','<','>','\\','@','_'}; for (int i=0;i<s->Length;i++) { bool gefunden=false; if (s[i]>='a' && s[i]<='z' && !gefunden) { gefunden=true; for (int o=0;o<6;o++) { new_matrix[6*i+o][0]=types[6*(s[i]-'a')+o][1]; } } if (s[i]>='A' && s[i]<='Z' && !gefunden) { gefunden=true; for (int o=0;o<6;o++) { new_matrix[6*i+o][0]=types[6*(s[i]-'A')+o][0]; } } if (s[i]>='0' && s[i]<='9' && !gefunden) { gefunden=true; for (int o=0;o<6;o++) { new_matrix[6*i+o][0]=types[6*(s[i]-'0')+o][2]; } } if (s[i]==' ' && !gefunden) { gefunden=true; for (int o=0;o<6;o++) { new_matrix[6*i+o][0]=0; } } if (!gefunden) { for (int t=0;t<29;t++) { gefunden=true; if (s[i]==extra_types[t]) for (int o=0;o<6;o++) { new_matrix[6*i+o][0]=types[6*t+o][3]; } } } } }Die Write-Funktion sieht etwas zerrissen aus, aber das liegt daran, dass ich nicht den kompletten ASCII-Code in meinem Bitmap habe.