【问题标题】:Fit Image into PictureBox使图像适合 PictureBox
【发布时间】:2013-05-25 04:48:32
【问题描述】:
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);
        }

    }
}

如果图像太大而无法容纳 picturebox。使图像适合picturebox 的代码是什么?

我的picturebox是正方形的,如果图片是矩形的,如何裁剪并像this一样显示在图片框中,图片的下半部分将被删除。

【问题讨论】:

    标签: c# winforms image picturebox


    【解决方案1】:

    首先,为了让任何图像“调整大小”以适合图片框,您可以设置PictureBox.SizeMode = PictureBoxSizeMode.StretchImage

    如果您想预先对图像进行剪裁(即切掉侧面或顶部和底部),那么您需要明确定义您想要的行为(从顶部开始,填充 pciturebox 的高度并裁剪其余部分,或从底部开始,将图片框的高度填充到顶部等),并且使用图片框和图像的Height / Width属性来剪切图像并获得您正在寻找的效果应该是相当简单的为。

    【讨论】:

      【解决方案2】:

      使用以下几行代码,您会找到解决方案...

      pictureBox1.ImageLocation = @"C:\Users\Desktop\mypicture.jpg";
      pictureBox1.SizeMode =PictureBoxSizeMode.StretchImage;
      

      【讨论】:

        【解决方案3】:

        查看图片框的 sizemode 属性。

        pictureBox1.SizeMode =PictureBoxSizeMode.StretchImage;
        

        【讨论】:

          【解决方案4】:

          伊玛目马赫迪

          您可以使用属性部分

          【讨论】:

            【解决方案5】:

            您可以将图片框的SizeMode属性设置为PictureSizeMode.Zoom,这将增加较小图像的大小或减小较大图像的大小以填充图片框

            【讨论】:

            • 顺便说一句,我在 Zoom 中遇到了一个奇怪的错误。即使在 Visual Studio 中设置为 Zoom,在代码中设置 Image 字段后,我不得不在代码中再次将 SizeMode 设置为 Zoom。否则,它不会缩小大图像。 (我用断点验证了它在设置图像时确实是缩放,但是直到我再次运行它并使用再次设置缩放的代码行时它才缩小。在两天内多次测试,以确保这真的正在发生。)
            【解决方案6】:

            PictureBox.SizeMode 选项缺少“填充”或“覆盖”模式,这与缩放类似,但需要裁剪以确保填充图片框。在 CSS 中,它是“封面”选项。

            此代码应启用:

            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;
            }
            

            【讨论】:

              【解决方案7】:

              您可以使用 PictureBox 控件的 SizeMode 属性并将其设置为 Center。 这将使图像的中心与图片框的中心相匹配。

              pictureBox1.SizeMode = PictureBoxSizeMode.CenterImage;
              

              希望对您有所帮助。

              【讨论】:

                【解决方案8】:

                您可以尝试更改 PictureBox 的 SizeMode 属性。

                您也可以将图像设置为 PictureBox 的 BackGroundImage 并尝试将 BackGroundImageLayout 更改为正确的模式。

                【讨论】:

                  【解决方案9】:

                  我在 VB 中有例程..

                  但是您应该有 2 个图片框 .. 1 个用于框架 .. 1 个用于图像 .. 它可以保持图片的大小比例

                  假设 picFrame 是图像帧,而 picImg 是图像

                  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
                  

                  我相信你可以把它做成 C# ....

                  【讨论】:

                    【解决方案10】:

                    要获得与 CSS 中 background-size: cover 模式类似的行为,您可以编写自己的派生 PictureBox 类,并重写 OnPaint 方法以实现您自己的自定义大小调整行为。

                    下面展示了一个我为此编写的自定义 PictureBox 实现,它具有“覆盖”和“适合”模式。该类具有设计器支持,因此可以在设计器中轻松更改属性,其结果将在视图中可见。请阅读以下说明以获取更多信息。

                    using System.ComponentModel;
                    using System.Drawing;
                    using System.Drawing.Drawing2D;
                    
                    // Source: https://stackoverflow.com/a/67452837/192077
                    
                    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;
                            }
                        }
                    }
                    

                    备注

                    在开发 Windows 窗体应用程序时,我还需要像 CSS 这样的“覆盖”行为,因此我决定编写自己的 PictureBox 实现。这个ResponsivePictureBox 类有一个名为ExtendedSizeMode 的新属性,它可以是CoverFitOff。封面模式模仿了 CSS 封面模式,并且 fit 类似于默认的 PictureBox “缩放”模式,但会尽可能以原始大小显示图像。

                    此外,当使用ExtendedSizeMode 时,新的ExtendedImageAlign 属性将在适当的角落对齐图像。

                    这个类还有一个InterpolationModePixelOffsetMode 属性,允许您进一步优化/自定义渲染。这是基于the post presented here

                    ExtendedSizeMode 设置为Off 时,PictureBox 将正常运行,但InterpolationModePixelOffsetMode 也将在默认模式下工作。

                    默认的Padding 属性也对适应和覆盖模式有影响,允许您偏移图片框内的图像。

                    附带说明:代码远非完美,因此请随时报告任何错误或进一步改进!

                    【讨论】:

                      猜你喜欢
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 2017-08-07
                      • 2019-07-10
                      • 1970-01-01
                      • 2021-04-08
                      • 1970-01-01
                      • 2011-10-24
                      相关资源
                      最近更新 更多