Fit Image into PictureBox
Asked Answered
A

11

84
using (SqlConnection myDatabaseConnection = new SqlConnection(myConnectionString.ConnectionString))
{
    myDatabaseConnection.Open();
    using (SqlCommand SqlCommand = new SqlCommand("Select Photo from Employee where EmpID LIKE '%' + @EmpID + '%' ", myDatabaseConnection))
    {
        SqlCommand.Parameters.AddWithValue("@EmpID", textBox1.Text);
        var DS = new DataSet();
        var adapter = new SqlDataAdapter(SqlCommand);
        adapter.Fill(DS, "Images");

        var imagesTable = DS.Tables["Images"];
        var imagesRows = imagesTable.Rows;
        var count = imagesRows.Count;

        if (count <= 0) return;

        var imageColumnValue =
            imagesRows[count - 1]["Image"];
        if (imageColumnValue == DBNull.Value)
            return;

        var data = (Byte[])imageColumnValue;
        using (var stream = new MemoryStream(data))
        {
            pictureBox1.Image = Image.FromStream(stream);
        }

    }
}

If the image is too large for the picturebox to fit. What is the code to make the image fit in the picturebox?

My picturebox is squared, if the image is rectangular how to it crop and show it in the picturebox like this, the lower part of the picture will be removed.

Antecede answered 29/5, 2013 at 19:18 Comment(0)
O
134

First off, in order to have any image "resize" to fit a picturebox, you can set the PictureBox.SizeMode = PictureBoxSizeMode.StretchImage

If you want to do clipping of the image beforehand (i.e. cut off sides or top and bottom), then you need to clearly define what behavior you want (start at top, fill the height of the pciturebox and crop the rest, or start at the bottom, fill the height of the picturebox to the top, etc), and it should be fairly simple to use the Height / Width properties of both the picturebox and the image to clip the image and get the effect you are looking for.

Oldenburg answered 29/5, 2013 at 19:21 Comment(0)
P
30

Use the following lines of code and you will find the solution...

pictureBox1.ImageLocation = @"C:\Users\Desktop\mypicture.jpg";
pictureBox1.SizeMode =PictureBoxSizeMode.StretchImage;
Pilloff answered 17/11, 2013 at 2:11 Comment(0)
I
26

Have a look at the sizemode property of the picturebox.

pictureBox1.SizeMode =PictureBoxSizeMode.StretchImage;
Isoniazid answered 28/3, 2018 at 11:15 Comment(0)
H
14

You can set picturebox's SizeMode property to PictureSizeMode.Zoom, this will increase the size of smaller images or decrease the size of larger images to fill the PictureBox

Horton answered 13/12, 2017 at 2:21 Comment(1)
BTW, I encountered a strange bug with Zoom. Even though it was set to Zoom in Visual Studio, after setting Image field in code, I had to set SizeMode to Zoom again in code. Otherwise, it didn't shrink a large image. (I verified with a breakpoint that it was indeed Zoom when it set the Image, but it didn't shrink until I ran again, with the line of code that set Zoom again. Tested multiple times over two days, to make sure this really was happening.)Phiona
D
13

Imam Mahdi aj SizeMode Change in properties

You can use the properties section

Deeann answered 19/2, 2018 at 15:34 Comment(0)
P
8

The PictureBox.SizeMode options are missing a "fill" or "cover" mode which would be like zoom except with cropping to ensure you're filling the picture box. In CSS it's the "cover" option.

This code should enable that:

static public void fillPictureBox(PictureBox pbox, Bitmap bmp)
{
    pbox.SizeMode = PictureBoxSizeMode.Normal;
    bool source_is_wider = (float)bmp.Width / bmp.Height > (float)pbox.Width / pbox.Height;

    var resized = new Bitmap(pbox.Width, pbox.Height);
    var g = Graphics.FromImage(resized);        
    var dest_rect = new Rectangle(0, 0, pbox.Width, pbox.Height);
    Rectangle src_rect;

    if (source_is_wider)
    {
        float size_ratio = (float)pbox.Height / bmp.Height;
        int sample_width = (int)(pbox.Width / size_ratio);
        src_rect = new Rectangle((bmp.Width - sample_width) / 2, 0, sample_width, bmp.Height);
    }
    else
    {
        float size_ratio = (float)pbox.Width / bmp.Width;
        int sample_height = (int)(pbox.Height / size_ratio);
        src_rect = new Rectangle(0, (bmp.Height - sample_height) / 2, bmp.Width, sample_height);
    }

    g.DrawImage(bmp, dest_rect, src_rect, GraphicsUnit.Pixel);
    g.Dispose();

    pbox.Image = resized;
}
Parthinia answered 13/5, 2019 at 20:28 Comment(0)
J
2

You could use the SizeMode property of the PictureBox Control and set it to Center. This will match the center of your image to the center of your picture box.

pictureBox1.SizeMode = PictureBoxSizeMode.CenterImage;

Hope it could help.

Janus answered 30/5, 2013 at 8:37 Comment(0)
B
1

I have routine in VB ..

but you should have 2 pictureboxes .. 1 for frame .. 1 for the image .. and it make keep the picture's size ratio

Assumed picFrame is the image frame and picImg is the image

Sub InsertPicture(ByVal oImg As Image)
    Dim oFoto As Image
    Dim x, y As Integer

    oFoto = oImg
    picImg.Visible = False
    picImg.Width = picFrame.Width - 2
    picImg.Height = picFrame.Height - 2
    picImg.Location = New Point(1, 1)
    SetPicture(picPreview, oFoto)
    x = (picImg.Width - picFrame.Width) / 2
    y = (picImg.Height - picFrame.Height) / 2
    picImg.Location = New Point(x, y)
    picImg.Visible = True

End Sub

I'm sure you can make it as C# ....

Bills answered 29/5, 2013 at 23:45 Comment(0)
L
0

You could try changing the: SizeMode property of the PictureBox.

You could also set your image as the BackGroundImage of the PictureBox and try changing the BackGroundImageLayout to the correct mode.

Lipinski answered 29/5, 2013 at 19:22 Comment(0)
C
0

To get similar behavior to the background-size: cover mode in CSS, you can write your own derived PictureBox class, and override the OnPaint method to implement your own custom sizing behavior.

Below is presented a custom PictureBox implementation I wrote to account for this, which has a "cover" and "fit" mode. The class has designer support, so properties can be easily changed in the designer of which the results will be visible in the view. Please read the notes below for additional info.

using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;

// Source: https://mcmap.net/q/240080/-fit-image-into-picturebox

namespace System.Windows.Forms.Derived
{
    public enum ExtendedPictureBoxSizeMode
    {
        Off = 0,
        Cover = 1,
        Fit = 2
    }

    public class ResponsivePictureBox : PictureBox
    {
        private ExtendedPictureBoxSizeMode extendedSizeMode = ExtendedPictureBoxSizeMode.Off;

        [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
        [DefaultValue(ExtendedPictureBoxSizeMode.Off)]
        [Category("Behavior")]
        public ExtendedPictureBoxSizeMode ExtendedSizeMode
        {
            get => extendedSizeMode;
            set
            {
                extendedSizeMode = value;
                Invalidate();
            }
        }

        private ContentAlignment extendedImageAlign = ContentAlignment.MiddleCenter;

        [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
        [DefaultValue(ContentAlignment.MiddleCenter)]
        [Category("Behavior")]
        public ContentAlignment ExtendedImageAlign
        {
            get => extendedImageAlign;
            set
            {
                extendedImageAlign = value;
                Invalidate();
            }
        }

        private InterpolationMode interpolationMode = InterpolationMode.Default;

        [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
        [DefaultValue(InterpolationMode.Default)]
        [Category("Behavior")]
        public InterpolationMode InterpolationMode
        {
            get => interpolationMode;
            set
            {
                if (value == InterpolationMode.Invalid)
                    return;

                interpolationMode = value;
                Invalidate();
            }
        }

        private PixelOffsetMode pixelOffsetMode = PixelOffsetMode.Default;

        [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
        [DefaultValue(PixelOffsetMode.Default)]
        [Category("Behavior")]
        public PixelOffsetMode PixelOffsetMode
        {
            get => pixelOffsetMode;
            set
            {
                if (value == PixelOffsetMode.Invalid)
                    return;

                pixelOffsetMode = value;
                Invalidate();
            }
        }

        // When changing the Padding property in the designer nothing seems to happen by default. Since our custom
        // control depends on the Padding property, we want the designer to repaint the control whenever its
        // value is changed, so we override the property and call Invalidate() in the setter to account for this.
        public new Padding Padding
        {
            get => base.Padding;
            set
            {
                base.Padding = value;
                Invalidate();
            }
        }

        protected override void OnPaint(PaintEventArgs pe)
        {
            pe.Graphics.InterpolationMode = InterpolationMode;
            pe.Graphics.PixelOffsetMode = PixelOffsetMode;

            if (ExtendedSizeMode == ExtendedPictureBoxSizeMode.Off || Image == null)
            {
                base.OnPaint(pe);
                return;
            }

            switch (ExtendedSizeMode)
            {
                case ExtendedPictureBoxSizeMode.Cover:
                    PaintCovered(pe);
                    return;

                case ExtendedPictureBoxSizeMode.Fit:
                    PaintFitted(pe);
                    return;
            }
        }

        private void PaintFitted(PaintEventArgs pe)
        {
            Rectangle rect = DeflateRect(ClientRectangle, Padding);

            if (rect.Height <= 0 || rect.Width <= 0) return;

            Image img = Image;
            int w, h;

            if (img.Width > rect.Width || img.Height > rect.Height)
            {
                if ((double)img.Width / img.Height > (double)rect.Width / rect.Height)
                {
                    w = rect.Width;
                    h = (int)((double)img.Height / img.Width * rect.Width);
                }
                else
                {
                    w = (int)((double)img.Width / img.Height * rect.Height);
                    h = rect.Height;
                }
            }
            else
            {
                w = img.Width;
                h = img.Height;
            }

            rect = GetAlignedContentRect(rect, w, h, ExtendedImageAlign);

            pe.Graphics.DrawImage(img, rect);
        }

        private void PaintCovered(PaintEventArgs pe)
        {
            Rectangle rect = DeflateRect(ClientRectangle, Padding);

            if (rect.Height <= 0 || rect.Width <= 0) return;

            Image img = Image;
            int w, h;

            if ((double)img.Width / img.Height > (double)rect.Width / rect.Height)
            {
                w = (int)((double)rect.Width / rect.Height * img.Height);
                h = img.Height;
            }
            else
            {
                w = img.Width;
                h = (int)((double)rect.Height / rect.Width * img.Width);
            }

            Rectangle imageRect = new Rectangle(0, 0, img.Width, img.Height);
            Rectangle portion = GetAlignedContentRect(imageRect, w, h, ExtendedImageAlign);

            pe.Graphics.DrawImage(img, rect, portion, GraphicsUnit.Pixel);
        }

        private static Rectangle GetAlignedContentRect(Rectangle containerRect, int contentW, int contentH, ContentAlignment imageAlign)
        {
            int containerW = containerRect.Width;
            int containerH = containerRect.Height;

            int x = (containerW - contentW) / 2;
            int y = (containerH - contentH) / 2;

            switch (imageAlign)
            {
                case ContentAlignment.TopLeft:
                    x = y = 0;
                    break;

                case ContentAlignment.TopCenter:
                    y = 0;
                    break;

                case ContentAlignment.TopRight:
                    x = containerW - contentW;
                    y = 0;
                    break;

                case ContentAlignment.MiddleRight:
                    x = containerW - contentW;
                    break;

                case ContentAlignment.BottomRight:
                    x = containerW - contentW;
                    y = containerH - contentH;
                    break;

                case ContentAlignment.BottomCenter:
                    y = containerH - contentH;
                    break;

                case ContentAlignment.BottomLeft:
                    x = 0;
                    y = containerH - contentH;
                    break;

                case ContentAlignment.MiddleLeft:
                    x = 0;
                    break;
            }

            return new Rectangle(containerRect.X + x, containerRect.Y + y, contentW, contentH);
        }

        public static Rectangle DeflateRect(Rectangle rect, Padding padding)
        {
            rect.X += padding.Left;
            rect.Y += padding.Top;
            rect.Width -= padding.Horizontal;
            rect.Height -= padding.Vertical;
            return rect;
        }
    }
}

Notes

While working on a Windows Forms application I also needed the "cover" behavior like CSS, so I decided to write my own PictureBox implementation. This ResponsivePictureBox class has a new property called ExtendedSizeMode which can be either Cover, Fit or Off. The cover mode mimics the CSS cover mode, and fit is similar to the default PictureBox "zoom" mode, but will try to display the image in its original size whenever possible.

Additionally, when ExtendedSizeMode is used, the new ExtendedImageAlign property will align the image in the appropriate corner.

This class also has an InterpolationMode and PixelOffsetMode property which allows you to further optimize/customize the rendering. This is based on the post presented here.

When ExtendedSizeMode is set to Off, the PictureBox will behave as normal, except for the InterpolationMode and PixelOffsetMode which will work in the default mode as well.

The default Padding property also has effect on both fit and cover modes, allowing you to offset the image inside the PictureBox.

Designer view

As a side note: The code is nowhere near perfect, so feel free to report any bugs, or improve it further!

Crimson answered 8/5, 2021 at 22:51 Comment(1)
Great solution, Thanks! However, setting the ImageLocation property again to change the current image doesn't seems to work. Not sure why.Sherbrooke
C
0

I encountered a similar problem and as I am new to C#, I used Microsoft Word to import the picture onto a page and resize it until it is relatively the size that I need it to be in the form. From there I just saved the image and imported it into the PictureBox.

Centrifugal answered 15/10, 2022 at 15:44 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.