2015-05-01 8 views
8

Ich mache ein Programm, das Bilder beschneidet. Ich habe zwei PictureBoxes und einen Button namens 'crop'. Ein Bildfeld enthält ein Bild. Wenn ich ein Rechteck auswähle und auf "Zuschneiden" drücke, wird der ausgewählte Bereich im anderen Bildfeld angezeigt. Das Programm funktioniert also, wenn ich auf "Crop" drücke. Das Problem ist: Wie kann ich das Bild aus dem Ausschnittbereich in das Bildboxbild bringen?Wie bekomme ich ein Bild von einem Rechteck?

Rectangle rectCropArea; 
Image srcImage = null; 

TargetPicBox.Refresh(); 
//Prepare a new Bitmap on which the cropped image will be drawn 
Bitmap sourceBitmap = new Bitmap(SrcPicBox.Image, SrcPicBox.Width, SrcPicBox.Height); 
Graphics g = TargetPicBox.CreateGraphics(); 

g.DrawImage(sourceBitmap, new Rectangle(0, 0, TargetPicBox.Width, TargetPicBox.Height), 
rectCropArea, GraphicsUnit.Pixel); 

//Good practice to dispose the System.Drawing objects when not in use. 
sourceBitmap.Dispose(); 

Image x = TargetPicBox.Image; 

Das Problem ist, dass x = null und das Bild wird in dem Bildfeld zeigt so, wie kann ich das Bild von diesem Bildfeld in die Image Variable bekommen?

Antwort

3

Ein paar Fragen:

  • Der erste und wichtigste: Sie sind verwirrt über die Beziehung zwischen PictureBox.Image (eine Eigenschaft) und der Graphics Sie mit der PictureBox ‚s Oberfläche assoziieren. Das Objekt Graphics, das Sie von Control.CreateGraphics erhalten, kann nur auf die Oberfläche des Steuerelements malen; normalerweise nicht was du willst; und selbst wenn Sie das tun, wollen Sie in der Regel in einem Paint Ereignis zu tun mit e.Graphics ..

So, während Ihr Code scheint zu funktionieren, ist es nur malt nicht-persistent Pixel auf der Oberfläche. Minimiere/maximiere und du wirst sehen, was nicht persistent bedeutet ..!

Um einen Bitmap bmp Sie es so mit einem Grahics Objekt verknüpfen müssen ändern:

Graphics g = Graphics.FromImage(bmp); 

Jetzt können Sie hinein ziehen:

g.DrawImage(sourceBitmap, targetArea, sourceArea, GraphicsUnit.Pixel); 

dass Nachdem Sie den Bitmap zuweisen können Die Image Eigenschaft der TargetPicBox ..

Schließlich entsorgen Sie die Graphics, oder besser, setzen Sie es in eine using Klausel ..

Ich gehe davon aus, dass Sie es geschafft haben, die rectCropArea sinnvolle Werte zu geben.

  • Beachten Sie auch, dass die Art und Weise Sie die Quell-Bitmap kopieren einen Fehler hat: Wenn Sie das vollständige Bild wollen, seineSize (*) nicht verwenden, nicht derjenige, der PictureBox !!

  • Und anstatt ein Zielrechteck mit demselben Fehler zu erstellen, verwenden Sie einfach TargetPicBox.ClientRectangle!

Hier ist ein Beispiel-Code für die Ernte Button:

// a Rectangle for testing 
Rectangle rectCropArea = new Rectangle(22,22,55,99); 
// see the note below about the aspect ratios of the two rectangles!! 
Rectangle targetRect = TargetPicBox.ClientRectangle; 
Bitmap targetBitmap = new Bitmap(targetRect.Width, targetRect.Height); 
using (Bitmap sourceBitmap = new Bitmap(SrcPicBox.Image, 
           SrcPicBox.Image.Width, SrcPicBox.Image.Height)) 
using (Graphics g = Graphics.FromImage(targetBitmap)) 
     g.DrawImage(sourceBitmap, targetRect, rectCropArea, GraphicsUnit.Pixel); 

if (TargetPicBox.Image != null) TargetPicBox.Dispose(); 
TargetPicBox.Image = targetBitmap; 
  • Natürlich sollten Sie das Rechteck in den richtigen Mausereignisse vorbereitet haben!
  • Hier würden Sie sich für das Seitenverhältnis des Ergebnisses entscheiden; Sie wollen das Ergebnis wahrscheinlich nicht verzerren! Sie müssen also entscheiden, ob Sie das Quell-Ausschnittsrechteck beschneiden oder das Zielrechteck erweitern möchten.

Beachten Sie, dass da ich zuweisen targetBitmap-TargetPicBox.Image Ich muss nicht dipose davon! Stattdessen, vor dem Zuweisen einer neuen Image, ich zuerst Dispose die alte ..