C# Bitmap x Spalten von hinten nach vorne setzen?

lordfritte

Lieutenant
Registriert
Juli 2006
Beiträge
1.006
Hallo ich arbeite gerade an einem ScrollLabel für fließende Texte und weil ich gerne eine flüssiges scrollen möchte, kommt ein einfaches char umsetzen für mich nicht in Frage.
Ich möchte mit einem Images arbeiten und einfach die Pixel umsetzen.
Jetzt ist meine Frage was ist die einfachste Möglichkeit in einem Bitmap die hinteren x Pixelspalten ab zu schneiden und wieder vorne an zu setzen?
Also Bitmap soll von der größe her gleich bleiben, ich möchte nur die hinteren x Spalten vorne an den Anfang de Bitmap's schreiben.

Also meine bisherige Vermutung ist ist:
Das ich also die hinteren x Pixelspalten in einem neuen Bitmap(Höhe: original Bitmap Höhe, Breite: x) sichern muss,
alle Pixel im original Bitmap um x Stellen nach hinten setzen muss und
anschließend die gesicherten Pixel wieder in das original Bitmap(pos.: 0, 1, 2, …, x) schreiben muss. Aber ich bin für einfachere Lösungen offen.
 
Zuletzt bearbeitet:
Zwischenfrage: Arbeitest du mit der WPF? Wenn ja, könntest du einfach eine Animation aufzeichnen.
 
gibts im visual studio denn keine ondraw() methode, wo du das element selbst zeichnen kannst? bevor du mit bildern anfängst, was ziemlich kompliziert werden kann, würde ich erst mal damit anfangen.
 
@msycho Nein ich arbeite mit der Window Form und den Text soll man ja natürlich auch ändern können.
@claW. Das Bitmap ist ja schon erstellt, ich möchte es dann nur immer umbauen, eben x Pixelspalten von hinten nach vorne.
 
Wie das Bitmap ist schon erstellt ?

Du musst sowieso das Bitmap jedes mal komplett neu zeichnen. Oder habe ich dich ned richtig verstanden?
 
Ja schon klar dass ich alles neu Zeichen muss....
Aber solange sich der Text nicht ändert kann ich ja immer ein Bitmap, welches in einem Bitmap Objekt gespeichert ist auf das Form Zeichen.

Aber meine Frage ist ob es eine einfache Möglichkeit gibt einfach x Pixel von gaaaanz hinten nach gaaaanz vorne zu setzen, ohne dass ich selber manuell jedes einzelne Pixel zu manipolieren brauche..
 
Bei den Überladungen der DrawImage-Klasse sollte auch eine deinen Zweck dabei sein. Hier ein kleines Beispiel:
Code:
    private void Form1_Paint(object sender, PaintEventArgs e) {
      Image img = Image.FromFile("bild.jpg");
      int x = 30;
      e.Graphics.DrawImage(img, new Rectangle(x, 0, img.Width - x, img.Height), new Rectangle(0, 0, img.Width - x, img.Height), GraphicsUnit.Pixel);
      e.Graphics.DrawImage(img, new Rectangle(0, 0, x, img.Height), new Rectangle(img.Width - x, 0, x, img.Height), GraphicsUnit.Pixel);
    }
 
Ein bißchen Quellcode besonders deine Ausgabe wäre nicht verkehrt.
Du kannst ja zum testen mal ein neues Projekt erstellen und mein Beispiel einfügen, dann wird vlt. ersichtlich was passiert.
 
Ja also es tut sich schon was, also er setzt die Pixel um, aber nur EIN mal, er soll es aber ständig machen, also die Pixel sollen im Kreis laufen, ich mache mal ein Beispiel mit zahlen.
123456
612345
561234
456123
345612
234561
123456

Aber zum quelltext:
PHP:
 public partial class ScrollLabel : UserControl
  {
    #region variablen

    private string _sText = "";
    private string _sCacheText = "";
    private int _iScrollAmount;
    private bool _bScroll = false;
    private Bitmap _bitMap = null;

    #endregion

    #region konstruktor

    public ScrollLabel()
    {
      InitializeComponent();
      timerScrollTimer.Start();
    }

    public ScrollLabel(IContainer container)
    {
      container.Add(this);
      InitializeComponent();
      timerScrollTimer.Start();
    }

    #endregion

    #region private Methoden

    void timerScrollTimer_Tick(object sender, System.EventArgs e)
    {
      Invalidate();
    }

    #endregion

    #region override Methoden

    protected override void OnPaint(PaintEventArgs e)
    {
      if (_bScroll)
      {
        //Hier komme ich nicht wirklich weiter.
      }
      else
        e.Graphics.DrawImageUnscaled(_bitMap, 0, 0);

      base.OnPaint(e);
    }

    #endregion

    #region public Properties

    public int ScrollInterval
    {
      get 
      {
        if (timerScrollTimer != null)
          return timerScrollTimer.Interval;
        else
          return 0;
      }
      set 
      { 
        if(timerScrollTimer != null)
          timerScrollTimer.Interval = value; 
      }
    }

    [DefaultValue(10)]
    public int ScrollPixelAmount
    {
      get
      {
        return _iScrollAmount;
      }
      set
      {
        _iScrollAmount = value;
      }
    }

    #endregion

    #region ovveride Properties

    [Browsable(true),
    DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
    public override string Text
    {
      get
      {
        return _sText;
      }
      set
      {
        _sText = value;

        Label label = new Label();
        label.Font = Font;
        label.Text = _sText;

        if (label.PreferredWidth > Size.Width)
          _bScroll = true;
        else
          _bScroll = false;

        if (_sCacheText.CompareTo(value) != 0)
        {
          _sCacheText = value;
          _bitMap = new Bitmap(Size.Width, Size.Height);
          Graphics g = Graphics.FromImage(_bitMap);
          g.FillRectangle(new SolidBrush(BackColor), new Rectangle(0, 0, Size.Width, Size.Height));

          if (label.PreferredWidth > Size.Width)  
            g.DrawString(_sText + " | ", Font, new SolidBrush(ForeColor), 0, 0);
          else
            g.DrawString(_sText, Font, new SolidBrush(ForeColor), 0, 0);

          g.Dispose();
        }

        Invalidate();
      }
    }

    #endregion
  }

also in InitializeComponent() steckt nur der Timer und das Fester selber.

EDIT: also mir deinem Beispiel habe ich es jetzt hin bekommen:
PHP:
Image img = Image.FromFile("bild.jpg");

    protected override void OnPaint(PaintEventArgs e)
    {
      int x = 5;
      Image img2 = new Bitmap(img);
      Graphics g = Graphics.FromImage(img);
      g.DrawImage(img2, 
        new Rectangle(x, 0, img.Width - x, img.Height), 
        new Rectangle(0, 0, img.Width - x, img.Height), 
        GraphicsUnit.Pixel);
      g.DrawImage(img2, 
        new Rectangle(0, 0, x, img.Height), 
        new Rectangle(img.Width - x, 0, x, img.Height), 
        GraphicsUnit.Pixel);

      e.Graphics.DrawImageUnscaled(img, 0, 0);

      base.OnPaint(e);
    }
 
Zuletzt bearbeitet:
Gut, und wenn das Bild jetzt fortlaufend "scrollen" soll, dann veränder einfach im Timer x bis maximal "img.Width" und setzt es dann wieder auf 0. Raufzählen, Null setzen, raufzählen, ... usw.
Ansonsten findet sich im C# Openbook auch ein paar Erklärungen und Beispiele zu C# und Grafiken.
 
Zuletzt bearbeitet:
Also es läuft trotzdem nicht so wirklich.. Ist das Label groß genug wo der Text rein passt läuft es schön rund.
Aber ist das Label jetzt kleiner als der Text(was ja der Sinn sein soll) dann läuft der Text auch rund, aber der Text ist voll verkrüppelt.
Ich muss da noch ein bisschen dran Arbeiten, solange muss ich mit meinem anderen Konzept arbeiten, dass ich eben doch die Char's weiter schiebe.
 

Ähnliche Themen

Zurück
Oben