vb@rchiv
VB Classic
VB.NET
ADO.NET
VBA
C#
Schützen Sie Ihre Software vor Software-Piraterie - mit sevLock 1.0 DLL!  
 vb@rchiv Quick-Search: Suche startenErweiterte Suche starten   Impressum  | Datenschutz  | vb@rchiv CD Vol.6  | Shop Copyright ©2000-2024
 
zurück

 Sie sind aktuell nicht angemeldet.Funktionen: Einloggen  |  Neu registrieren  |  Suchen

VB.NET - Ein- und Umsteiger
Genaue Breite eines Strings ermitteln 
Autor: Kalli
Datum: 30.05.18 17:57

Ich versuche vergeblich in VB Net die genaue Breite eines Strings in Pixeln zu ermitteln. Wie ich die Suche danach auch anstelle, ich lande immer bei einer Form von "MeasureText", was als size nur eine ungenaue Höhe und Breite liefert, sodass man z.B. in einer PictureBox keine Chance hat, ein Caret genau hinter einen existierenden Grafiktext zu platzieren. Zur Bestimmung der minimalen Texthöhe gibt es einige Texteigenschaften, die man von der durch "MeasureText" gelieferten Höhe abziehen kann, aber für die Textbreite scheinen solche Regularien in VB Net vollkommen zu fehlen.
Könnt Ihr mir helfen?

Dont debug, because there will allways be one more bug

Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Genaue Breite eines Strings ermitteln 
Autor: Manfred X
Datum: 30.05.18 19:32

Hallo!

Probiere mal so ...
Public Class frmTextWidth
 
    Dim pb As New PictureBox With {.Parent = Me, .Dock = DockStyle.Fill}
    Dim bmp As New Bitmap(300, 300)
 
 
    Private Sub frmTextWidth_Load(sender As Object, _
        e As EventArgs) Handles MyBase.Load
 
        Dim txt As String = "Irgendein Text"
        Dim fo As New Font("Arial", 14, FontStyle.Bold)
 
        Using gr As Graphics = Graphics.FromImage(bmp),
                br As New SolidBrush(Color.Black)
            With gr
                .Clear(Color.White)
                .DrawString(txt, fo, br, New Point(20, 20))
                Dim ts As SizeF = .MeasureString(txt, fo)
                .FillRectangle(br, ts.Width + 20, 20, ts.Height, ts.Height)
            End With
        End Using
 
        pb.Image = bmp
 
    End Sub
End Class
Bei einem mehrzeiligen oder umbrochenen Text könntest Du jede Zeile
einzeln in der Box plazieren und ausmessen.

Beitrag wurde zuletzt am 30.05.18 um 19:39:28 editiert.
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Genaue Breite eines Strings ermitteln 
Autor: Kalli
Datum: 30.05.18 20:08

Vielen Dank für Deine Mühe. Das Problem ist, dass Du auch von "MeasureText" ausgehst, was eine zu große Breite liefert.
Ich komme mit Deinem gefüllten Rechteck nicht so ganz klar: Breite und Höhe gleich?
.FillRectangle(br, ts.Width + 20, 20, ts.Height, ts.Height)
Aber selbst, wenn Du Dich vertippt hast und meinst:
.FillRectangle(br, ts.Width + 20, 20, ts.Width, ts.Height)
ist die size "ts" nicht genau passend, sondern etwas zu groß. Das ist genau mein Problem.
Ich habe versucht, das Problem zu lösen, indem ich den Text schwarz mit schwarzem Hintergrund auf eine weiße Bitmap schreibe und dann die schwarzen Pixel in Höhe und Breite auslese. Das liefert mir das exakte Ergebnis, könnte aber bei einem langsamen Rechner zu Verzögerungen bei der Texteingabe führen.
Kalle

Dont debug, because there will allways be one more bug

Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Genaue Breite eines Strings ermitteln 
Autor: Manfred X
Datum: 30.05.18 20:31

Probiere mal die StringFormat-Methode und die StringFormatFlags-Enumeration:

https://docs.microsoft.com/de-de/dotnet/api/system.drawing.stringformatflags?view=netframework-4.7.2

Du mußt bei der Beurteilung auch berücksichtigen, daß die Pixel-Darstellung nur eine
begrenzte Genauigkeit bietet.
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Genaue Breite eines Strings ermitteln 
Autor: Kalli
Datum: 31.05.18 00:18

Hallo Manfred X,
vielen Dank. Da war ich schon, habe aber nicht alles verstanden. Zum Probieren bin ich noch nicht gekommen. Ich werde es die Tage nach Deinem Vorschlag nochmal durchprobieren und bei Erfolg hier posten.

Dont debug, because there will allways be one more bug

Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Genaue Breite eines Strings ermitteln 
Autor: Manfred X
Datum: 31.05.18 06:08

MeasureText oder MeasureString ?
https://stackoverflow.com/questions/6704923/textrenderer-measuretext-and-graphics-measurestring-mismatch-in-size

Details:
http://web.archive.org/web/20100116044507/http://windowsclient.net/articles/gdiptext.aspx

Beitrag wurde zuletzt am 31.05.18 um 06:13:45 editiert.
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Genaue Breite eines Strings ermitteln 
Autor: Kalli
Datum: 01.06.18 08:54

Hallo Manfred X,
entschuldige die späte Antwort, war zu sehr mit Brötchen verdienen beschäftigt.
Ich habe den Unterschied zwischen TextRenderer.MeasureText und Grapics.MeasureString ausprobiert. Es bringt leider nur ein paar Pixel, aber in der Bemessung der Textbreite nicht genau den Punkt, wo der nächste Buchstabe eines neuen Strings ansetzen müsste.

Hier der Code, den ich zum Ausprobieren benutzt habe:
Public Class Form1
    Dim s As String, fo As Font
 
 
    Private Sub Bild_Paint(sender As Object, e As PaintEventArgs) Handles _
      Bild.Paint
        Dim hdc As IDeviceContext
        hdc = e.Graphics
        fo = New Font("Calligraph421 BT", 40, FontStyle.Regular)
        s = "Alle meine Entchen"
        Dim si As Size = TextRenderer.MeasureText(s, fo)
        Dim si1 As SizeF = e.Graphics.MeasureString(s, fo)
        Debug.Print(si.Width.ToString + " " + si.Height.ToString)
        Dim bm As New Bitmap(Bild.Width, Bild.Height)
        Bild.Image = bm
        Using gr As Graphics = Graphics.FromImage(Bild.Image)
            gr.DrawString(s, fo, Brushes.Black, New Point(0, 0))
            gr.DrawRectangle(Pens.Red, New Rectangle(0, 0, si1.Width, _
              si1.Height))
            TextRenderer.DrawText(gr, s, fo, New Point(0, 40), Color.Black)
            gr.DrawRectangle(Pens.Red, New Rectangle(0, 40, si.Width, _
              si.Height))
        End Using
    End Sub
End Class
Ich werde aber noch weiter herumprobieren (In GFA-Basic hatte ich dafür eine Methode "Text.Width", die die exakte Breite lieferte, "Text.Height" lieferte einen sauberen Zeilenabstand ohne viel Klimbim)
Bis ev. in ein paar Tagen, hab so viel anderes Zeug um die Ohren.
Kalle

Dont debug, because there will allways be one more bug

Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Genaue Breite eines Strings ermitteln 
Autor: GPM
Datum: 01.06.18 13:07

Mal mit TextFormatFlags.NoPadding testen:

Public Class Form1
    Dim WithEvents Pb As New PictureBox With {.Dock = DockStyle.Fill, _
      .BackColor = Color.Black, .Parent = Me}
    Dim Fo As New Font("Arial", 40)
 
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Me.Width = 700
    End Sub
 
    Private Sub Pb_Paint(sender As Object, e As PaintEventArgs) Handles Pb.Paint
        Dim str As String = "ABCD56789 i Q y {}³z", s = "", sz As Size
        For i = 1 To str.Length
            s = str.Substring(0, i)
            sz = TextRenderer.MeasureText(e.Graphics, s, Fo, New Size, _
              TextFormatFlags.NoPadding)
            TextRenderer.DrawText(e.Graphics, s, Fo, New Point(0, 0), _
            Color.Yellow, TextFormatFlags.NoPadding)
            e.Graphics.DrawRectangle(Pens.White, New Rectangle(New Point(0, 0), _
            sz))
        Next
    End Sub
End Class
MfG GPM
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Genaue Breite eines Strings ermitteln 
Autor: Kalli
Datum: 01.06.18 16:44

Danke GPM,
hörte sich toll an, aber das "NoPadding" wirkt sich leider nicht auf MeasureText aus. Das angezeigte umschließende Rechteck verändert seine Größe nicht. Was ich brauche, sind die Maße in Pixeln (oder sonst etwas) die das Recheck hat, welches den Texthintergrund bildet. Bis jetzt bin ich immer noch beim Auszählen der Pixel des Hintergrundrechtecks.

Using gr As Graphics = Graphics.FromImage(Bild.Image)
            Dim si As Size = TextRenderer.MeasureText(s, fo, New Size, _
              TextFormatFlags.NoPadding)
            TextRenderer.DrawText(gr, s, fo, New Point(0, 0), Color.Black, _
            Color.White, TextFormatFlags.NoPadding)
            gr.DrawRectangle(Pens.Red, New Rectangle(0, 0, si.Width, si.Height))
        End Using
Kalle

Dont debug, because there will allways be one more bug

Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Genaue Breite eines Strings ermitteln 
Autor: GPM
Datum: 01.06.18 18:21

Es entspricht aber auch nicht meinem Beispiel (gr fehlt)

Public Class Form1
    Dim WithEvents Pb As New PictureBox With {.Dock = DockStyle.Fill, _
      .BackColor = Color.Black, .Parent = Me}
    Dim Fo As New Font("Arial", 40)
 
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Me.Width = 700
    End Sub
 
    Private Sub Pb_Paint(sender As Object, e As PaintEventArgs) Handles Pb.Paint
        Dim s As String = "Alle meine Entchen"
        Dim gr As Graphics = e.Graphics
 
        Dim si As Size = TextRenderer.MeasureText(s, Fo, New Size, _
          TextFormatFlags.NoPadding)
        TextRenderer.DrawText(gr, s, Fo, New Point(0, 0), Color.Black, _
        Color.White, TextFormatFlags.NoPadding)
        gr.DrawRectangle(Pens.Red, New Rectangle(0, 0, si.Width, si.Height))
 
        si = TextRenderer.MeasureText(gr, s, Fo, New Size, _
          TextFormatFlags.NoPadding)
        TextRenderer.DrawText(gr, s, Fo, New Point(0, 100), Color.Yellow, _
        Color.Blue, TextFormatFlags.NoPadding)
        gr.DrawRectangle(Pens.White, New Rectangle(0, 100, si.Width, si.Height))
    End Sub
End Class
MfG GPM
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Genaue Breite eines Strings ermitteln 
Autor: Kalli
Datum: 01.06.18 18:59

Wow - mit dem Device-Context klappt es!!!!!(hatte ich übersehen.)
Danke! Die so ermittelte Textbreite und -Höhe entspricht genau dem Hintergrund.
Hier nochmal das Wesentliche für alle, die das gleiche Problem haben:
 Using gr As Graphics = Graphics.FromImage(Bild.Image)
            Dim si As Size = TextRenderer.MeasureText(gr, s, fo, New Size, _
              TextFormatFlags.NoPadding)
            TextRenderer.DrawText(gr, s, fo, New Point(0, 0), Color.Black, _
            Color.White, TextFormatFlags.NoPadding)
            'gr.DrawString(s, fo, Brushes.Black, New Point(0, 0)) nicht 
            ' benutzen!
            gr.DrawRectangle(Pens.Red, New Rectangle(0, 0, si.Width, si.Height))
        End Using
"Bild" = PictureBox
"s"= String
"fo" = Font
Achtung! Mit "gr.DrawString" funktioniert es nicht! Das sind zwei Welten.
Kalle

Dont debug, because there will allways be one more bug

Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Sie sind nicht angemeldet!
Um auf diesen Beitrag zu antworten oder neue Beiträge schreiben zu können, müssen Sie sich zunächst anmelden.

Einloggen  |  Neu registrieren

Funktionen:  Zum Thema  |  GesamtübersichtSuchen 

nach obenzurück
 
   

Copyright ©2000-2024 vb@rchiv Dieter Otter
Alle Rechte vorbehalten.
Microsoft, Windows und Visual Basic sind entweder eingetragene Marken oder Marken der Microsoft Corporation in den USA und/oder anderen Ländern. Weitere auf dieser Homepage aufgeführten Produkt- und Firmennamen können geschützte Marken ihrer jeweiligen Inhaber sein.

Diese Seiten wurden optimiert für eine Bildschirmauflösung von mind. 1280x1024 Pixel