Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Crop and Print Image Documents without Distortion In C#

I'm using WinForms. In my form I have a picturebox I use to display image documents. The problem is when I crop the image and then print the document out the image becomes slightly distorted. If I don't crop the image document and print it regularly the image document does not become distorted.

How do I crop and print the image documents without them being distorted?

Or is there a better way to code this so it can crop and print without the image document being distorted? If so, how can i do it?

Notes:

  • My picturebox is set to Zoom because the images i work with is big:

  • Example of image document Dimensions: 2500 x 3100

  • My picturebox does not have a border

    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: Slightly Distorted:

enter image description here

Test: Not Distorted:

enter image description here

enter image description here

Test: The picture above is a test. This is what happened when i took the below code out from pictureBox1_MouseUp:

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

And edited/replaced (originalImage to pictureBox1.Image):

g.DrawImage(pictureBox1.Image, 0, 0, rect, GraphicsUnit.Pixel);
like image 261
taji01 Avatar asked Feb 01 '16 02:02

taji01


1 Answers

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

That is most likely where the problem started. This can cause pictureBox1.Image to be rescaled to force-fit it to the pictureBox1 size. Depends on whether the picturebox has borders and its SizeMode property value. Rescaling causes the image to be resampled, the color of a pixel in the new bitmap is calculated from the values of its neighboring pixels in the original image as directed by the selected InterpolationMode.

This in effect blurs the resulting image. That works well on a photo but this is text that critically depends on anti-aliasing pixels to look decent on a low-resolution monitor. Slight changes to those pixels ruins the effect and they no longer smoothly blend the letter shape against the background anymore. They become more visible, best way to describe it is that the resulting text looks "fat".

I see no obvious reason to do this at all in the posted code. Delete the statement and replace originalImage with pictureBox1.Image.

Also beware that printing this image is likely to be disappointing. Now those anti-aliasing pixels get turned into 6x6 blobs of ink on paper. That only ever looks good when you have long arms. As long as the font size is this small and you have no control over the anti-aliasing choice then there's very little you can do about that. Printed text only ever looks good when you use PrintDocument and Graphics.DrawString().

like image 141
2 revs Avatar answered Oct 14 '22 11:10

2 revs