Laden...

Ausschnitt einer PictureBox in eine Bitmap kopieren

Erstellt von TEry vor 16 Jahren Letzter Beitrag vor 16 Jahren 5.063 Views
T
TEry Themenstarter:in
98 Beiträge seit 2007
vor 16 Jahren
Ausschnitt einer PictureBox in eine Bitmap kopieren

Hallo,

im Moment suche ich mich dumm und dämlich. Nicht das ich net schon einige Bücher gelesen hätte, das halbe iNet durchsucht hätte, aber der Kopf wird grösser und Grösser und bevor er platzt, dachte ich, eine Frage zu stellen ...

Das Problem ist eigentlich echt simpel.

Ich habe eine PictureBox in die ich an verschiedene Stellen was zeichne oder schreibe. Es sind jedoch keine Grafiken zu laden.

Ein einfaches Beispiel:
In Bereich 0,0,39,39 der PictureBox1 wird eine rote Zahl 12 mit Graphics.DrawString("12",usw )
geschrieben.

ich soll nun nur den Bereich von x=0 bis 39 und y = 0-39 in eine Bitmap kopieren können, dort bearbeiten und zurück in die PictureBox kopieren.

Es gibt natürlich auch Bereiche von x=40-79 und y = 120-159. Und ich brauche exakt diesen Bereich in der Bitmap.

Wie ich das drehe, wende oder so, ist eigentlich nicht das Problem, sondern, wie bringe ich einen bestimmten Bereich einer PictureBox in eine Bitmap.

Eine Bitmap in die Picturebox zu zeichnen, ist kein Prob.

Hat vielleicht jemand einen Tip, bevor es Nacht wird?

Vielen Dank und nette Grüsse an Alle hier,

TEry

T
TEry Themenstarter:in
98 Beiträge seit 2007
vor 16 Jahren

Naja das Problem hatte ich gedacht zu lösen, indem ich eine vordefinierte Image von 512x512 in die Picturebox geladen habe. Das Problem ist nur das über
Graphics g = pictureBox1.CreateGraphics();
und die darauf folgenden Draw - Operanten, scheinbar nicht in auf das Image der Picturebox, sondern in die Picturebox selber geschreiben wird.

Hat irgend jemand eine Idee?


public Form1()
{
   InitializeComponent();
   pictureBox1.Image = Image.FromFile(@"D:\Test\leer512x512.jpg");
   tempImage32x32 = Image.FromFile(@"D:\Test\leer32x32.jpg");
   tempImage = pictureBox1.Image;
   tempBitmap = (Bitmap)tempImage;
}

private Image tempImage;
private Image tempImage32x32;
private Bitmap tempBitmap;

public void showZahl(int i)
{
    Graphics g = pictureBox1.CreateGraphics();
    SolidBrush sB = new SolidBrush(Color.Black);
    Font f = new Font("Arial",12);
    g.DrawString(i.ToString(), f, sB, 10, 10);
    f.Dispose();
    sB.Dispose();
    g.Dispose();
}

private bool istShowZahl = false;

private void button1_Click(object sender, EventArgs e)
{
   if (!istShowZahl)
   {
      istShowZahl = true;
      showZahl(12);
   }
   else
   {
       Graphics g = pictureBox1.CreateGraphics();
       Bitmap b = new Bitmap(tempImage40x40);
       for (int x = 0; x < 32; x++)
       {
           for (int y = 0; y < 32; y++)
          {
              Color cN = tempBitmap.GetPixel(x, y);
              b.SetPixel(x, y, cN);
           }
        }
        g.DrawImage(b, 32, 32);
        g.Dispose();
    }
}

Danke und Gruss TEry

5.742 Beiträge seit 2007
vor 16 Jahren

Wie wäre es, wenn du es so löst (ungetestet!):


public partial class Form //und so weiter
{
    private Bitmap bitmap;
    
    public Form()
    {
        this.bitmap = new Bitmap(picturebox1.Width, picturebox1.Height);
        picturebox1.Image = this.bitmap;
    }

    public void Zeichnen()
    {
         Graphics g = Graphics.FromImage(this.bitmap);
         // weiterer Code
    }

    public Bitmap Teilstück(Rectangle rect)
    {
        return this.bitmap.Clone(rect,  System.Drawing.Imaging.PixelFormat.DontCare);
    }

}

T
TEry Themenstarter:in
98 Beiträge seit 2007
vor 16 Jahren

hi und vielen Danke winSharp93!

Es klappt endlich, auch wenn die gesammt Bitmap nach jeder Zeichenoperation, die so klein sie auch ist, auf die pictureBox.Image kopiert werden muss. Ich finde es jedoch sehr intressant, weil man immer einen Buffer hat in dem sich das Orginal befindet. Nur, so ganz glücklich bin ich noch nicht, aber man kann immerhin damit werkeln 🙂

In diesen Sinn nochmals Danke!!! und Gruss
TEry

5.742 Beiträge seit 2007
vor 16 Jahren

Du kannst es natürlich auch so lösen:


public partial class Testform : Form
{
   public Testform()
   {
      InitializeComponent();
      pictureBox1.Image = new Bitmap(pictureBox1.Width, pictureBox1.Height);
    }

    private void zeichnen()
    {
       Graphics g = Graphics.FromImage(pictureBox1.Image);
       g.DrawEllipse(new Pen(Color.Black), new Rectangle(new Point(0, 0), new Size(pictureBox1.Width, pictureBox1.Height)));
       g.Dispose();
       pictureBox1.Refresh();
    }
}

In Zeichnen kannst du alles bearbeiten - egal, ob du etwas hinzufügst, entfernst oder überzeichnest. Dann brauchst du auch nicht mehr immer einen Ausschnitt erstellen und diesen anschließend wieder zurückkopieren.

Edit:

Original von TEry
Es klappt endlich, auch wenn die gesammt Bitmap nach jeder Zeichenoperation, die so klein sie auch ist, auf die pictureBox.Image kopiert werden muss.

Warum muss die Bitmap kopiert werden? Bitmap ist eine Klasse und somit ein Referenztyp.

T
TEry Themenstarter:in
98 Beiträge seit 2007
vor 16 Jahren

hi winSharp93,

echt toll!!! Zudem wird, was mich etwas verwundert tempBitmap, welche auf dieselbe Adresse zu zeigen scheint, gleichwohl mit Daten beschreiben ... 🙂 ! ?.
Nur kannst du pictureBox1.Image = new Bitmap(oldBitmap, width, height) nicht ohne Referenz auf eine bestehendes Model öffnen. Aber das habe ich jetzt gelöst und poste später gern noch die Lösung fals sie jemand intressiert.

*verbeugend* TEry

T
TEry Themenstarter:in
98 Beiträge seit 2007
vor 16 Jahren

hi,
hier noch die Lösung.
Nochmals Danke an winSharp93!

echt tool Leute, manchmal ist es einfach schön, hier sein zu dürfen!!!

Gruss TEry


public Form1()
{
  InitializeComponent();
  Image i = Image.FromFile(@"D:\Eigene Dateien\leer640x640.jpg");
  tempBitmap = (Bitmap)i;
  pictureBox1.Image = tempBitmap;
  tempImage40x40 = Image.FromFile(@"D:\Eigene Dateien\leer40x40.jpg");
  showZahl(1);
}
       
private Image tempImage40x40;
private Bitmap tempBitmap;

public void showZahl(int i)
{
   Graphics g = Graphics.FromImage(pictureBox1.Image);
   SolidBrush sB = new SolidBrush(Color.Black);
   Font f = new Font("Arial",32);
   g.DrawString(i.ToString(), f, sB, 0, 0);
   f.Dispose();
   sB.Dispose();
   g.Dispose();
   pictureBox1.Refresh();
}

private Bitmap getBitmap(int posx, int posy)
{
   return tempBitmap.Clone(new Rectangle(posx,posy,40,40), PixelFormat.DontCare);
}

private void button1_Click(object sender, EventArgs e)
{
   Graphics g = Graphics.FromImage(pictureBox1.Image);
   Bitmap bMap40x40 = new Bitmap(tempImage40x40);
   bMap40x40 = getBitmap(0, 0);
   // zum Drehen
   //  bMap40x40.RotateFlip(RotateFlipType.Rotate90FlipX);
   g.DrawImage(bMap40x40, 40,40);
   g.Dispose();
   pictureBox1.Refresh();
}

Edit: und hier noch ein Test mit dem drehen.


Array rT = Enum.GetValues(typeof(RotateFlipType));
int x = 40;
int y = 0;
for (int i = 0; i < rT.Length; i++)
{
  RotateFlipType rFType = (RotateFlipType)rT.GetValue(i);
  bMap40x40.RotateFlip(rFType);
  g.DrawImage(bMap40x40, x, y);
  richTextBox1.AppendText(i.ToString()+": "+rFType.ToString() + "\n");
  x += 40;
  if (x== 4 * 40)
  {
    x = 0;
    y += 40;
  }
}