Text auf einen Bild verschieben

  • VB.NET

Es gibt 9 Antworten in diesem Thema. Der letzte Beitrag () ist von ErfinderDesRades.

    Text auf einen Bild verschieben

    Hallo zusammen,
    Ich habe eine Frage zu einen Projekt.

    Ich habe eine Vorlage und füge einene Text mit Hilfe X und Y Parameter mit

    VB.NET-Quellcode

    1. Graphic.DrawString
    ein.
    Dass geht und läuft tadellos. Das Text Positionieren íst nur etwas aufwendig. ;)

    Ich möchte den Text in Echtzeit auf den Bild mit Hilfe zwei Scrollbar verschieben danach die X und Y Parameter speichern, ist so etwas mit VB möglich?

    *Topic verschoben*

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Marcus Gräfe“ ()

    Quick and dirty

    Ja ganz bestimmt... :)

    Für die X-Achse hab ich das kurz realisiert (klick .gif im Anhang). Für die Y-Achse ist es dann das Gleiche nur mit Y.Value.

    ACHTUNG ist 100% schlechte Lösung wegen des ständigen neu Ladens der Bilddatei bei jedem Trackbar Event/Scrollbar-Event.

    C# Code:

    C#-Quellcode

    1. public partial class Form1 : Form
    2. {
    3. readonly string imageFilePath = @"Wald.jpg"; //PicturePath
    4. readonly string TextOnPic = "HELLO THERE!"; //Your Text
    5. PointF txtLocation = new(0f, 200f); //TextPosition
    6. public Form1()
    7. {
    8. InitializeComponent();
    9. CenterToParent();
    10. TrkbarX_Scroll(null,null);
    11. }
    12. private void TrkbarX_Scroll(object? sender, EventArgs? e)
    13. {
    14. var tmpBitmap = (Bitmap)Image.FromFile(imageFilePath);
    15. txtLocation.X = TrkbarX.Value;
    16. using (Graphics graphics = Graphics.FromImage(tmpBitmap))
    17. {
    18. using Font arialFont = new("Arial", 72);
    19. graphics.DrawString(TextOnPic, arialFont, Brushes.White, txtLocation);
    20. }
    21. PicbxShow.Image = tmpBitmap;
    22. TxbxX.Text = $"{TrkbarX.Value}";
    23. }
    24. }





    Vielleichte können die anderen Forums-Nutzer noch etwas dazu schreiben, wie man das Problem des ständigen Ladens des .jpgs eleganter lösen kann :)

    lg nogood
    Bilder
    • TxtOnImage.gif

      663,47 kB, 670×652, 78 mal angesehen
    codewars.com Rank: 4 kyu

    nogood schrieb:

    wie man das Problem des ständigen Ladens des .jpgs eleganter lösen kann


    Einfach eine abgeleitete PictureBox machen, eine Klasse für den Text, da kannst du auch selbst noch mehr Felder hinzufügen(Farbe, Font etc.). So lässt sich auch leicht das verwenden von mehreren Texten mit unterschiedlichen Styles einbauen. Wenn nur 1 Text pro PB gemalt werden soll, kannst du die Klasse PictureBoxExText ersatzlos streichen, dann aber auch die Control.Text Property der PBex wieder sichtbar machen und nutzen.

    VB.NET-Quellcode

    1. Imports System.ComponentModel
    2. Imports System.Drawing.Imaging
    3. Public Class PictureBoxEx
    4. Inherits PictureBox
    5. Private pictureBoxExText As New PictureBoxExText()
    6. Public Sub New()
    7. Font = New Font("Microsoft Sans Serif", 8.25F)
    8. End Sub
    9. Public Sub SetPictureBoxExText(text As String)
    10. pictureBoxExText.Text = text
    11. Invalidate()
    12. End Sub
    13. Public Sub SetPictureBoxExTextPosition(position As Point)
    14. pictureBoxExText.Position = position
    15. Invalidate()
    16. End Sub
    17. Public Sub Export(filename As String, imageFormat As ImageFormat)
    18. If IO.File.Exists(filename) Then
    19. If MessageBox.Show("Datei existiert bereits, überschreiben?", "Appname", MessageBoxButtons.YesNoCancel) <> DialogResult.Yes Then
    20. Return
    21. End If
    22. End If
    23. 'Bitmap erstellen(mit using Anweisung!), sowohl Image wie auch den Text drauf malen und speichern
    24. End Sub
    25. <Browsable(True)>
    26. <EditorBrowsable(EditorBrowsableState.Always)>
    27. Public Overloads Property Font As Font
    28. Protected Overrides Sub OnPaint(e As PaintEventArgs)
    29. MyBase.OnPaint(e)
    30. 'todo:
    31. 'die anderen Fälle im Select vervollständigen
    32. Select Case SizeMode
    33. Case PictureBoxSizeMode.StretchImage
    34. If Not Image Is Nothing Then e.Graphics.DrawImage(Image, 0, 0, Width, Height)
    35. e.Graphics.DrawString(pictureBoxExText.Text, Font, Brushes.Black, pictureBoxExText.Position)
    36. Case PictureBoxSizeMode.Normal
    37. e.Graphics.DrawString(pictureBoxExText.Text, Font, Brushes.Black, pictureBoxExText.Position)
    38. Case PictureBoxSizeMode.AutoSize
    39. e.Graphics.DrawString(pictureBoxExText.Text, Font, Brushes.Black, pictureBoxExText.Position)
    40. Case PictureBoxSizeMode.CenterImage
    41. e.Graphics.DrawString(pictureBoxExText.Text, Font, Brushes.Black, pictureBoxExText.Position)
    42. Case PictureBoxSizeMode.Zoom
    43. End Select
    44. End Sub
    45. End Class
    46. Class PictureBoxExText
    47. Public Text As String
    48. Public Position As New Point
    49. Public Sub New()
    50. End Sub
    51. Public Sub New(text As String)
    52. Me.Text = text
    53. End Sub
    54. Public Sub New(text As String, position As Point)
    55. Me.Text = text
    56. Me.Position = position
    57. End Sub
    58. End Class

    Bessere Lösung

    Auf @-Franky- Anregung, falls ich das in etwa richtig interpretiert habe. Hier noch eine bessere Lösung, für das 'Text'-Bewegen auf einem Bild.
    Idee ist, eine Picturebox als Hintergrund, mit dem jpg als Image. Darauf ein Label setzen (Background Transperent). Als Parent des Lables dient dann die Picturebox.
    Per Scroll wird dann nur der Text verschoben. Das .jpg wird nur einmal geladen.
    Wenn die Koordinaten dann später fest stehen, kann man immer noch den Text mit dem Bild verbinden.

    C#
    Spoiler anzeigen

    C#-Quellcode

    1. using System;
    2. using System.Collections.Generic;
    3. using System.ComponentModel;
    4. using System.Data;
    5. using System.Drawing;
    6. using System.Linq;
    7. using System.Text;
    8. using System.Threading.Tasks;
    9. using System.Windows.Forms;
    10. namespace WF_TextOnImageV2
    11. {
    12. public partial class Form1 : Form
    13. {
    14. Point txtLocation = new Point(0, 0); //TextPosition
    15. public Form1()
    16. {
    17. InitializeComponent();
    18. CenterToParent();
    19. txtLocation = new Point(PicbxBg.Location.X, PicbxBg.Location.Y);
    20. PicbxBg.BackgroundImage = Image.FromFile(@"deinImg.jpg");
    21. LbTxt.Location = txtLocation;
    22. LbTxt.Parent = PicbxBg;
    23. LbTxt.Text = "TEST";
    24. LbTxt.BackColor = Color.Transparent;
    25. }
    26. private void ScrbrTxt_X_Scroll(object sender, ScrollEventArgs e)
    27. {
    28. txtLocation.X = ScrbrTxt_X.Value;
    29. LbTxt.Location = txtLocation;
    30. }
    31. }
    32. }


    konvertiert via OnlineConvert nach VB

    VB.NET-Quellcode

    1. Public Partial Class Form1
    2. Inherits Form
    3. Private txtLocation As Point = New Point(0, 0)
    4. Public Sub New()
    5. InitializeComponent()
    6. CenterToParent()
    7. txtLocation = New Point(PicbxBg.Location.X, PicbxBg.Location.Y)
    8. PicbxBg.BackgroundImage = Image.FromFile("deinImg.jpg")
    9. LbTxt.Location = txtLocation
    10. LbTxt.Parent = PicbxBg
    11. LbTxt.Text = "TEST"
    12. LbTxt.BackColor = Color.Transparent
    13. End Sub
    14. Private Sub ScrbrTxt_X_Scroll(ByVal sender As Object, ByVal e As ScrollEventArgs)
    15. txtLocation.X = ScrbrTxt_X.Value
    16. LbTxt.Location = txtLocation
    17. End Sub
    18. End Class
    codewars.com Rank: 4 kyu
    Also so gesehen das gleiche wie ich zeigte nur mit einem Label, da ist eine abgeleitete PictureBox doch besser, so wird auch nur 1 mal in das Bild gerendert(beim Export), erspart sich aber das Label, richtig gemacht, kann man dann auch alles im Designer einstellen(Text(e), Farben, Fonts usw...). Das alles dann in einem Control.
    ich finde die beidden Varianten überhaupt nicht gleich - nichtmal ähnlich.
    Die erste ist aufwändig, mit Vererbung und OwnerDrawing: 70 zeilen.
    Die zweite ist simpel, mit Composition und ohne selbstgebastelte Controls: 20 Zeilen. Allerdings auch noch ohne Export-Funktion.

    Generell gilt: Composition over Inheritance.
    Weil bei Composition kann man sich die Features, die man braucht , je nach Bedarf hinzufügen und andere weglassen.
    Bei Inheritance kann man nix weglassen, sodass eine Neigung zu immer mehr Erben besteht, oder aber der Versuch, eine eierlegende Wollmilchsau zu fabrizieren.