2016-02-01 13 views
14

Ich verwende WinForms. In meinem Formular habe ich eine Bildbox, mit der ich Bilddokumente anzeigen kann. Das Problem ist, wenn ich das Bild beschneide und dann das Dokument ausdruck, wird das Bild leicht verzerrt. Wenn ich das Bilddokument nicht zuschneide und es regelmäßig drucke, wird das Bilddokument nicht verzerrt.Zuschneiden und Drucken von Bilddokumenten ohne Verzerrung in C#

Wie kann ich die Bilddokumente zuschneiden und drucken, ohne dass sie verzerrt sind?

Oder gibt es eine bessere Möglichkeit, dies zu kodieren, damit es beschneiden und drucken kann, ohne dass das Bilddokument verzerrt wird? Wenn ja, wie kann ich es tun?

Hinweise:

  • Mein picturebox ist auf Zoom, weil die Bilder i mit groß arbeiten:

  • Beispiel für Bilddokument Abmessungen: 2500 x 3100

  • Meine picturebox hat keine Grenze

    int _cropX, _cropY, _cropWidth, _cropHeight; 
    public Pen _cropPen; 
    private State _currentState; 
    
    private enum State 
    { 
        Crop 
    } 
    
    private void Open_btn_Click(object sender, EventArgs e) 
    { 
        // open file dialog 
        OpenFileDialog open = new OpenFileDialog(); 
    
        if (open.ShowDialog() == DialogResult.OK) 
        { 
         // display image in picture box 
         pictureBox1.Image = new Bitmap(open.FileName); 
        } 
    } 
    
    private void pictureBox1_MouseUp(object sender, MouseEventArgs e) 
    { 
        try 
        { 
         if (Crop_Checkbox.Checked == true) 
         { 
          Cursor = Cursors.Default; 
          if (_currentState == State.Crop) 
          { 
           if (_cropWidth < 1) 
           { 
            return; 
           } 
    
           Rectangle rect = new Rectangle(_cropX, _cropY, _cropWidth, _cropHeight); 
           //First we define a rectangle with the help of already calculated points 
    
           Bitmap originalImage = new Bitmap(pictureBox1.Image, pictureBox1.Width, pictureBox1.Height); 
           //Original image 
    
           Bitmap img = new Bitmap(_cropWidth, _cropHeight); 
           // for cropinf image 
    
           Graphics g = Graphics.FromImage(img); 
           // create graphics 
    
           g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; 
           g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality; 
           g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality; 
           //set image attributes 
    
           g.DrawImage(originalImage, 0, 0, rect, GraphicsUnit.Pixel); 
    
           pictureBox1.Image = img; 
           pictureBox1.Width = img.Width; 
           pictureBox1.Height = img.Height; 
          } 
    
         } 
         else 
         { 
          Cursor = Cursors.Default; 
         } 
        } 
        catch (Exception) 
        { 
    
        } 
    } 
    
    private void pictureBox1_MouseMove(object sender, MouseEventArgs e) 
    { 
        if (Crop_Checkbox.Checked == true) 
        { 
         if (_currentState == State.Crop) 
         { 
          Cursor = Cursors.Cross; 
          if (e.Button == System.Windows.Forms.MouseButtons.Left) 
          { 
           //X and Y are the coordinates of Crop 
           pictureBox1.Refresh(); 
           _cropWidth = e.X - _cropX; 
           _cropHeight = e.Y - _cropY; 
           pictureBox1.CreateGraphics().DrawRectangle(_cropPen, _cropX, _cropY, _cropWidth, _cropHeight); 
          } 
    
         } 
        } 
        else 
        { 
         Cursor = Cursors.Default; 
        } 
    
    } 
    
    private void Crop_Checkbox_CheckedChanged(object sender, EventArgs e) 
    { 
        if (Crop_Checkbox.Checked == true) 
        { 
         this.Cursor = Cursors.Cross; 
        } 
    } 
    
    private void Print_btn_Click(object sender, EventArgs e) 
    { 
        System.Drawing.Printing.PrintDocument myPrintDocument1 = new System.Drawing.Printing.PrintDocument(); 
        PrintDialog myPrinDialog1 = new PrintDialog(); 
        myPrintDocument1.PrintPage += new System.Drawing.Printing.PrintPageEventHandler(printDocument1_PrintPage); 
        myPrinDialog1.Document = myPrintDocument1; 
    
    
        if (myPrinDialog1.ShowDialog() == DialogResult.OK) 
        { 
         myPrintDocument1.Print(); 
        } 
    } 
    
    private void printDocument1_PrintPage(object sender, PrintPageEventArgs e) 
    { 
        e.Graphics.DrawImage(pictureBox1.Image, 10, 10); //(Standard paper size is 850 x 1100 or 2550 x 3300 pixels) 
    } 
    
    private void pictureBox1_MouseDown(object sender, MouseEventArgs e) 
    { 
        if (Crop_Checkbox.Checked == true) 
        { 
         if (_currentState == State.Crop) 
         { 
          if (e.Button == System.Windows.Forms.MouseButtons.Left) 
          { 
           Cursor = Cursors.Cross; 
           _cropX = e.X; 
           _cropY = e.Y; 
    
           _cropPen = new Pen(Color.FromArgb(153, 180, 209), 3); //2 is Thickness of line 
    
           _cropPen.DashStyle = DashStyle.DashDotDot; 
           pictureBox1.Refresh(); 
          } 
         } 
        } 
        else 
        { 
         Cursor = Cursors.Default; 
        } 
    
    } 
    

enter image description here

Test: leicht verzerrt:

enter image description here

Test: Verfälschungen schützt:

enter image description here

enter image description here

Test: Das obige Bild ist ein Test. Dies ist, was passiert, wenn ich den Code unten aus pictureBox1_MouseUp heraus nahm:

Bitmap originalImage = new Bitmap(pictureBox1.Image, pictureBox1.Width, pictureBox1.Height); 

und bearbeitet/ersetzt (originalImage zu pictureBox1.Image):

g.DrawImage(pictureBox1.Image, 0, 0, rect, GraphicsUnit.Pixel); 
+0

Ich kann nicht wirklich die "Verzerrung" sehen. Welche Art von Verzerrung begegnet Ihnen? – Ian

+0

Wenn Sie das Dokument regelmäßig drucken, sehen Sie es klarer. Die Wörter haben eine kleine Verzerrung @lan – taji01

+0

Ich kann immer noch nicht die Verzerrung im Bild sehen? Du scheinst das Bild nicht zu zeigen, oder? – Ian

Antwort

1
Bitmap originalImage = new Bitmap(pictureBox1.Image, pictureBox1.Width, pictureBox1.Height); 

Das ist höchstwahrscheinlich, wo das Problem gestartet. Dies kann dazu führen, dass imageBox1.Image neu skaliert wird, um es an die pictureBox1-Größe anzupassen. Hängt davon ab, ob die Bildbox über Rahmen und den SizeMode-Eigenschaftswert verfügt. Die Neuskalierung bewirkt, dass das Bild erneut abgetastet wird, und die Farbe eines Pixels in der neuen Bitmap wird aus den Werten seiner benachbarten Pixel in dem ursprünglichen Bild gemäß der Anweisung des ausgewählten Interpolationsmodus berechnet.

Dies verwischt in der Tat das resultierende Bild. Das funktioniert gut auf einem Foto, aber das ist Text, der kritisch von Anti-Aliasing-Pixeln abhängt, um auf einem Monitor mit niedriger Auflösung gut auszusehen. Geringfügige Änderungen an diesen Pixeln ruinieren den Effekt und sie fügen die Buchstabenform nicht mehr nahtlos in den Hintergrund ein. Sie werden sichtbarer, der beste Weg, um es zu beschreiben ist, dass der resultierende Text "fett" aussieht.

Ich sehe keinen offensichtlichen Grund, dies überhaupt im geposteten Code zu tun.Löschen Sie die Anweisung, und ersetzen Sie OriginalImage durch pictureBox1.Image.

Achten Sie auch darauf, dass das Drucken dieses Bildes wahrscheinlich enttäuschend sein wird. Jetzt werden diese Anti-Aliasing-Pixel in 6x6 Farbkleckse auf Papier verwandelt. Das sieht nur gut aus, wenn man lange Arme hat. Solange die Schriftgröße so klein ist und Sie keine Kontrolle über die Anti-Aliasing-Wahl haben, können Sie sehr wenig dagegen tun. Gedruckter Text sieht immer nur dann gut aus, wenn Sie PrintDocument und Graphics.DrawString() verwenden.

+0

Danke für Ihre Erklärung. Ich überprüfe gerade meinen Code und sehe, ob das Problem behoben ist. – taji01

+0

Wenn ich das originalImage herausziehe und es durch pictureBox1.Image ersetze. Das Programm schneidet nicht korrekt ab. Wenn das originalImage nicht mehr angezeigt wird, zeigt das Programm nur einen Teil des Bildes an. – taji01

+0

Das hilft mir nicht, Ihnen zu helfen, der Punkt des Zuschneidens ist, "etwas vom Bild zu zeigen". Die _cropXxx-Werte sind Bildfeldkoordinaten, keine Bildkoordinaten. Dieser Code kann nur funktionieren, wenn die SizeMode-Eigenschaft AutoSize entspricht. Dass in der SizeMode-Eigenschaft etwas nicht stimmt, wurde bereits in der Antwort angenommen und erklärt die Neuskalierungsartefakte. Sie müssen seinen Wert dokumentieren. –