Search code examples
c#.netwinformsuser-interface

BAD IMAGE QUALITY (Bitmap Windows Forms C#)


Im making a functionnality to add image to a page, but when i save it the quality is just horrible. Is there a way to make it look way better? Code :

using (Bitmap bmp = new Bitmap(pageImage.Width, pageImage.Height))
{
    pageImage.DrawToBitmap(bmp, new Rectangle(0, 0, pageImage.Width, pageImage.Height)); // pageImage is a pictureBox
    bmp.Save(originalLocation);
}

Image Example

on the right, the original image, on the left, the saved image from bitmap (im doing a functionnality to add image to image). As you can see, there is a big quality difference. Is there a way to keep the same quality?


Solution

  • I was using the PictureBox's size instead of the one of PictureBox.Image on the bitmap, and using the PictureBox.DrawToBitmap() method.

    Solution :

    using (Bitmap bmp = new Bitmap(pageImage.Image.Width, pageImage.Image.Height))
    {
        using (Graphics g = Graphics.FromImage(bmp))
        {
            g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
            g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
            g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
    
            if (pageImage.Image != null)
            {
                g.DrawImage(pageImage.Image, new Rectangle(0, 0, bmp.Width, bmp.Height));
            }
    
            float scaleX = (float)bmp.Width / pageImage.Width;
            float scaleY = (float)bmp.Height / pageImage.Height;
    
            foreach (Control control in pageImage.Controls)
            {
                if (control is PictureBox pictureBox && pictureBox.Image != null)
                {
                    int x = (int)(pictureBox.Left * scaleX);
                    int y = (int)(pictureBox.Top * scaleY);
    
                    using (Image overlayImage = pictureBox.Image)
                    {
                        float aspectRatio = (float)overlayImage.Width / overlayImage.Height;
                        int destWidth = (int)(pictureBox.Width * scaleX);
                        int destHeight = (int)(pictureBox.Height * scaleY);
    
                        if (pictureBox.SizeMode == PictureBoxSizeMode.Zoom)
                        {
                            if (destWidth > destHeight * aspectRatio)
                            {
                                destWidth = (int)(destHeight * aspectRatio);
                            }
                            else
                            {
                                destHeight = (int)(destWidth / aspectRatio);
                            }
                        }
    
                        int destX = x + (int)((pictureBox.Width * scaleX - destWidth) / 2);
                        int destY = y + (int)((pictureBox.Height * scaleY - destHeight) / 2);
    
                        g.DrawImage(overlayImage, new Rectangle(destX, destY, destWidth, destHeight));
                    }
                }
            }
        }
    
        bmp.Save(originalLocation, ImageFormat.Png);
    }```