用C#缩放图像

时间:2012-11-05 03:03:23

标签: c# winforms image-processing

我在缩放图像时遇到问题。我已成功缩放图像,但图像在向上或向下滚动时会中断。

public partial class ImageDetail : UserControl
{
    public delegate void onClose();
    public event onClose close;
    Image pbImage;
    public ImageDetail(Image img)
    {            
        InitializeComponent();
        pictureBox.Image = img;
        pbImage = img;
        pictureBox.Width = this.pbImage.Width;
        pictureBox.Height = this.pbImage.Height;
        panel2.AutoScroll = true;
        panel2.HorizontalScroll.Maximum = img.Width;
        panel2.VerticalScroll.Maximum   = img.Height;
        panel2.HorizontalScroll.Minimum = 0;
        panel2.VerticalScroll.Minimum   = 0;
        panel2.SetAutoScrollMargin(10, 10);            
    }

    private void label2_Click(object sender, EventArgs e)
    {
        if (close != null)
            close(); 
    }        

    private void DrawImage(int startX, int startY)
    {            
        if (this.pbImage == null) { return; }

        Graphics pbGraphics = this.pictureBox.CreateGraphics();
        BufferedGraphicsContext currentGraphicsContext = BufferedGraphicsManager.Current;
        Rectangle targetRect = new Rectangle(startX, startY, (this.pbImage.Width + tmpWidth), (this.pbImage.Height + tmpHeight));
        using (BufferedGraphics pbGDIBuffer = currentGraphicsContext.Allocate(pbGraphics, targetRect))
        {
            Rectangle drawRect = new Rectangle(startX, startY, (this.pbImage.Width + tmpWidth), (this.pbImage.Height + tmpHeight));

            pbGDIBuffer.Graphics.DrawImageUnscaledAndClipped(this.pbImage, drawRect);
            pbGDIBuffer.Render();                
        }
        pictureBox.Width = this.pbImage.Width + tmpWidth;
        pictureBox.Height = this.pbImage.Height + tmpHeight;
    }             

    int tmpWidth = 0, tmpHeight = 0;
    private void toolStripSplitButton1_ButtonClick(object sender, EventArgs e)
    {
        tmpWidth = tmpWidth + ((this.pbImage.Width * 20) / 100);
        tmpHeight = tmpHeight + ((this.pbImage.Height * 20) / 100);

        pictureBox.Width = this.pbImage.Width + tmpWidth;
        pictureBox.Height = this.pbImage.Height + tmpHeight;
        pictureBox.Refresh();
        DrawImage(0, 0);
    }

    private void toolStripSplitButton2_ButtonClick(object sender, EventArgs e)
    {
        if(tmpWidth > 0)
            tmpWidth = tmpWidth - ((this.pbImage.Width * 20) / 100);
        if(tmpHeight > 0)
            tmpHeight = tmpHeight - ((this.pbImage.Height * 20) / 100);
        if (tmpHeight < 0)
            tmpHeight = 0;
        if (tmpWidth < 0)
            tmpWidth = 0;
        pictureBox.Refresh();
        DrawImage(0, 0);                      
    }

    private void panel2_MouseDown(object sender, MouseEventArgs e)
    {
        pictureBox.Width = this.pbImage.Width + tmpWidth;
        pictureBox.Height = this.pbImage.Height + tmpHeight;
    }

    private void panel2_MouseUp(object sender, MouseEventArgs e)
    {
        pictureBox.Width = this.pbImage.Width + tmpWidth;
        pictureBox.Height = this.pbImage.Height + tmpHeight;
    }

}

2 个答案:

答案 0 :(得分:2)

您应该在Paint事件(例如)上绘制图像:

pictureBox.Paint += (sender, e) =>
    {
        var drawRect = new Rectangle(startX, startY, pictureBox.Width, pictureBox.Height);
        e.Graphics.DrawImageUnscaledAndClipped(this.pbImage, drawRect);
    };

并在调整Invalidate方法调整大小后:

pictureBox.Invalidate();

你的代码应该是这样的:

public ImageDetail(Image img)
{
    pictureBox.Image = img;
    pbImage = img;
    ...
    pictureBox.Paint += pictureBox_Paint;
}

void pictureBox_Paint(object sender, PaintEventArgs e)
{
    if (pbImage == null) { return; }
    var drawRect = new Rectangle(startX, startY, pictureBox.Width, pictureBox.Height);
    e.Graphics.DrawImageUnscaledAndClipped(this.pbImage, drawRect);
}

private void toolStripSplitButton1_ButtonClick(object sender, EventArgs e)
{
    ///... resize to what you need 
    pictureBox.Width = (int) (pbImage.Width*0.2);
    pictureBox.Height = (int) (pbImage.Height * 0.2);
    pictureBox.Invalidate();
}

答案 1 :(得分:0)

不使用图片框缩放图像。这是缩放代码,它将缩放使用 c# 中的 Graphcs.DrawImage 方法绘制的图像。希望您能理解。check ImageZoom.cs

或者这里是代码。

   public static  class ImageZoom
{
 /// <summary>
 /// returns the zoomed rectangle to zoom an image
 /// </summary>
 /// <param name="imageRectangle">display rectangle of given image</param>
 /// <param name="mousepoint">current position of mouse</param>
 /// <param name="zoomFactor">positive value to zoom in and negetive value to zoom out </param>
 /// <returns></returns>
    public static RectangleF Zoom(RectangleF imageRectangle, Point mousepoint, float zoomFactor)
    {
        //orginal size and location of image
        SizeF OrginalSize = imageRectangle.Size;
        PointF Orginalpoint = imageRectangle.Location;
        //Mouse cursor location -located in width% and height% of totaloriginal image
        float mouse_widthPercent = System.Math.Abs(Orginalpoint.X - mousepoint.X) / OrginalSize.Width * 100;
        float mouse_heightPercent = System.Math.Abs(Orginalpoint.Y - mousepoint.Y) / OrginalSize.Height * 100;


        //Zoomed Image by scalefactor
        SizeF newSize = new SizeF(
             OrginalSize.Width + OrginalSize.Width * zoomFactor,
             OrginalSize.Height + OrginalSize.Height * zoomFactor
             );

        if (newSize.Width > 50000 || newSize.Height > 50000 || newSize.Width < 10 || newSize.Height < 10)
            return imageRectangle;

        //How much width increases and height increases
        float width_incrasesBy = newSize.Width - OrginalSize.Width;
        float height_incresesBy = newSize.Height - OrginalSize.Height;

        //Adjusting Image location after zooming the image
        PointF newPoint = new PointF(

              Orginalpoint.X - width_incrasesBy * mouse_widthPercent / 100,

              Orginalpoint.Y - height_incresesBy * mouse_heightPercent / 100

              );
       
        return new RectangleF(newPoint, newSize);

    }

    

}