Forum: PC-Programmierung Java: Umwandeln von Glyphs fehlerhaft


von Robert S. (razer) Benutzerseite


Lesenswert?

Hallo an alle,

Ich schreibe gerade ein Tool, das mir einen Zeichensatz mit einer 
bestimmten Font in ein "Pixel-Array" umwandelt, um es für ein LCD zu 
nutzen.

Dazu habe ich eine Klasse, die mir genau ein Zeichen Umwandelt. Ich gebe 
das konvertierte Zeichen per Ascii-Art auf der Konsole aus. Leider 
werden manche Zeichen unvollständig erzeugt:

H:
1
        
2
 #      
3
 #      
4
 #      
5
 #      
6
 #######
7
 ##    #
8
 #      
9
 #      
10
 #      
11
 #

N:
1
        
2
 ##     
3
 ##     
4
 ###    
5
 # ##   
6
 #  #   
7
 #   #  
8
 #   ## 
9
 #    ##
10
 #     #
11
 #     #
Die beiden Zeichen sind Arial, 14.

Hierzu der Konstruktor der Klasse:
1
public LcdGlyph(String c, Font f)
2
    {
3
        this.c = c;
4
        this.f = f;
5
6
        FontRenderContext fontRendContext = new FontRenderContext(null, true, true);
7
        GlyphVector glyphVector = f.createGlyphVector(fontRendContext, c);
8
9
        Rectangle2D bounds = glyphVector.getPixelBounds(fontRendContext, 0, 0);
10
        int width = (int)bounds.getWidth();
11
        int height = (int)bounds.getHeight();
12
13
        BufferedImage bn = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_BINARY);
14
        Graphics2D g2d = bn.createGraphics();
15
        g2d.drawGlyphVector(glyphVector, 0,(float)height);
16
17
        WritableRaster raster = bn.getRaster();
18
        DataBuffer buffer = raster.getDataBuffer();
19
        SampleModel model = bn.getSampleModel();
20
21
        for(int i=0; i<raster.getHeight(); i++)
22
        {
23
            for(int j=0; j<raster.getWidth(); j++)
24
            {
25
                int pixel[] = model.getPixel(j, i, (int[])null, buffer);
26
27
                if(pixel[0]>0)
28
                {
29
                    System.out.print("#");
30
                }
31
                else
32
                {
33
                    System.out.print(" ");
34
                }
35
36
            }
37
            System.out.println();
38
        }
39
    }

Andere Zeichen werden richtig erzeugt.

Kann mir jemand Tipps dazu geben?

lg Robert

von Marvin (Gast)


Lesenswert?

Es sieht ganz so aus, als ob irgendwo in deinem Programm deine Grafik in 
der Breite abgeschnitten wird. Kann es evtl hier sein:

Robert S. schrieb:
1
g2d.drawGlyphVector(glyphVector, 0,(float)height);

(Ich habe keine Ahnung... aber der Aufruf sieht mir irgendwie 
unsymmetrisch aus ;) )

Gruesse

Marvin

von Robert S. (razer) Benutzerseite


Lesenswert?

Das denke ich nicht.
Es wird dabei die Y-Startposition um die Höhe nach unten verschoben, 
denn drawGlyphVector() schreibt von unten nach oben.

Es geht um die X-Achse. In Y werden alle richtig gezeichnet.

von Reinhard Kern (Gast)


Lesenswert?

Hallo,

warum zeichnest du das Zeichen nicht einfach auf den Windows-Bildschirm 
und fragst die Pixel ab? Das heisst du benutzt den Renderer von Windows 
und nicht etwas Unbekanntes.

Gruss Reinhard

von Robert S. (razer) Benutzerseite


Lesenswert?

Wie würdest du das lösen?
Mit der Klasse Canvas komme ich erstmal nicht zurecht, denn die muss 
einem Frame zugeordnet werden, bevor darauf gezwichnet werden kann.

Irgendwie mit JPanel??

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Also....
Ein Buffered Image ist hierfür erstmal völlig korrekt!
Das ganze auf den Bildschirm zu zeichnen macht nur mehr Probleme als das 
es hilft.

Du solltest aber den Fontrenderkontext des BI nutzen und nicht einen 
eigenen erstellen!
Unter Umständen solltest du außerdem mal vom GV die getVisualBounds() 
Methode nutzen, sowie das BI mal auf einem Label zur Anzeige bringen ob 
das ganze ein Zeichenproblem ist oder ob deine Konvertierung BI --> 
ASCII irgendwie spinnt.

In diesem Falle läßt sich der Pixelwert auch viel einfacher direkt über 
das BI mittels getRGB(intx int y) abfragen.

von Robert S. (razer) Benutzerseite


Lesenswert?

Läubi .. schrieb:
> Du solltest aber den Fontrenderkontext des BI nutzen und nicht einen
> eigenen erstellen!
> Unter Umständen solltest du außerdem mal vom GV die getVisualBounds()
> Methode nutzen, sowie das BI mal auf einem Label zur Anzeige bringen ob
> das ganze ein Zeichenproblem ist oder ob deine Konvertierung BI -->
> ASCII irgendwie spinnt.

Danke für die Tipps. Dazu habe ich noch Fragen. Um ein BufferedImage zu 
erzeugen, benötige ich deren Größe. Wenn ich daraus den FontRenderer 
erzeuge weiß ich vorher noch nicht wie groß das Glyph sein wird:
1
BufferedImage bn = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_BINARY);
2
GlyphVector glyphVector = f.createGlyphVector(g2d.getFontRenderContext(), c);
3
g2d.drawGlyphVector(glyphVector, 0,(float)height);

lg Robert

von Claudio H. (bastelfinger)


Lesenswert?

GlyphVector.getGlyphOutline().getPathIterator(),

dann mit currentSegment() und next() die Koordinaten abfragen.

EDIT: Das geht dann ohne zu zeichnen. Aber du kannst dir auch einen 
eigenen Graphic-Context für die Konsole schreiben. Wäre dann natürlich 
eleganter. Aber wie oben beschrieben ist auf jeden Fall eine gute Lösung 
ohne den Aufwand beim Zeichnen auf ein Control!

von Claudio H. (bastelfinger)


Lesenswert?

Noch etwas:
Beim KKonstruktor vom FontRenderContext schaltest du AntiAliasing ein. 
Willst du das wirklich so haben?

von Claudio H. (bastelfinger)


Lesenswert?

>Rectangle2D bounds

hier solltest du nicht mit bounds.getHeight() weitermachen, und auf int 
casten, sondern gleich bounds.getSize().getHeight verwenden. Generell 
solltest du die vielen Casts vermeiden.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.