我想知道,一旦我将图像加载到Windows窗体中,有没有办法允许用户拖动该图像的角落并重新调整大小?
目前,我知道PictureBox.Scale方法(但不推荐使用)。我也知道PictureBox.Image.Size。这是否意味着每次重新调整大小时我都需要使用PictureBox.Image.Size?另外,我如何允许他们抓取图像以重新调整大小?我想我正在考虑绘画以及它如何允许用户选择图像,然后通过拖动角落重新调整尺寸...
我不是在寻找一个完整的解决方案 - 只是在正确方向上的一些指针(伪代码或一般描述来帮助我的思维过程会很好)。我不太确定如何解决这个问题。
到目前为止,这是我的代码:
using (OpenFileDialog ofd = new OpenFileDialog())
{
ofd.Title = "Load Image";
if (ofd.ShowDialog() == DialogResult.OK)
{
PictureBox pictureBox = new PictureBox();
pictureBox.Image = new Bitmap(ofd.FileName);
pictureBox.SizeMode = PictureBoxSizeMode.StretchImage;
pictureBox.Size = pictureBox.Image.Size;
panelArea.Controls.Add(pictureBox);
}
}
答案 0 :(得分:6)
Winforms中已有一个控件可以显示位图并支持使用鼠标调整大小:表单。你只需要做一点手术就可以把它变成一个控制:
using (OpenFileDialog ofd = new OpenFileDialog()) {
ofd.Title = "Load Image";
if (ofd.ShowDialog() == DialogResult.OK) {
var box = new Form();
box.TopLevel = box.ControlBox = false;
box.Visible = true;
box.BackgroundImage = new Bitmap(ofd.FileName);
panelArea.Controls.Add(box);
box.Size = box.BackgroundImage.Size;
}
}
答案 1 :(得分:2)
编辑:在您的情况下,Hans Passant的方法是最好的。我会保留我的答案,以防你最终有更复杂的编辑要求(例如,拖动多个形状)
有趣的是让鼠标互动起作用。现在,让我们假设您只想通过拖动图像的右下角来调整大小。我会做这样的事情:
创建一个名为ImageCanvas
的UserControl。在此控件内,执行以下操作:
添加字段以跟踪图片的大小/位置,可能是Rectangle imageRect
覆盖OnPaint
方法以显示图片:
protected override void OnPaint(PaintEventArgs e)
{
e.Graphics.DrawImage(image, imageRect);
}
添加字段以跟踪用户何时调整图片大小,例如bool isDraggingSize
覆盖OnMouseDown
和OnMouseUp
。当鼠标按钮分别向下或向上时,设置或清除isDraggingSize
。
覆盖OnMouseMove
以执行以下操作:
设置光标:如果isDraggingSize
或鼠标指针靠近图像的右下角,请设置Cursor = Cursors.SizeNWSE
;否则,请设置Cursor = Cursors.Default
。
如果isDraggingSize
,请根据鼠标位置更改imageSize
字段。如有必要,请致电Invalidate()
或Refresh()
以更新显示。
使用它,并修复所有小细节 - 比如决定当用户尝试调整大于控件的图像大小时会发生什么,以及如何摆脱闪烁。
答案 2 :(得分:0)
public Bitmap _currentBitmap;
public void Resize(int newWidth, int newHeight)
{
if (newWidth != 0 && newHeight != 0)
{
Bitmap temp = (Bitmap)_currentBitmap;
Bitmap bmap = new Bitmap(newWidth, newHeight, temp.PixelFormat);
double nWidthFactor = (double)temp.Width / (double)newWidth;
double nHeightFactor = (double)temp.Height / (double)newHeight;
double fx, fy, nx, ny;
int cx, cy, fr_x, fr_y;
Color color1 = new Color();
Color color2 = new Color();
Color color3 = new Color();
Color color4 = new Color();
byte nRed, nGreen, nBlue;
byte bp1, bp2;
for (int x = 0; x < bmap.Width; ++x)
{
for (int y = 0; y < bmap.Height; ++y)
{
fr_x = (int)Math.Floor(x * nWidthFactor);
fr_y = (int)Math.Floor(y * nHeightFactor);
cx = fr_x + 1;
if (cx >= temp.Width) cx = fr_x;
cy = fr_y + 1;
if (cy >= temp.Height) cy = fr_y;
fx = x * nWidthFactor - fr_x;
fy = y * nHeightFactor - fr_y;
nx = 1.0 - fx;
ny = 1.0 - fy;
color1 = temp.GetPixel(fr_x, fr_y);
color2 = temp.GetPixel(cx, fr_y);
color3 = temp.GetPixel(fr_x, cy);
color4 = temp.GetPixel(cx, cy);
// Blue
bp1 = (byte)(nx * color1.B + fx * color2.B);
bp2 = (byte)(nx * color3.B + fx * color4.B);
nBlue = (byte)(ny * (double)(bp1) + fy * (double)(bp2));
// Green
bp1 = (byte)(nx * color1.G + fx * color2.G);
bp2 = (byte)(nx * color3.G + fx * color4.G);
nGreen = (byte)(ny * (double)(bp1) + fy * (double)(bp2));
// Red
bp1 = (byte)(nx * color1.R + fx * color2.R);
bp2 = (byte)(nx * color3.R + fx * color4.R);
nRed = (byte)(ny * (double)(bp1) + fy * (double)(bp2));
bmap.SetPixel(x, y, System.Drawing.Color.FromArgb(255, nRed, nGreen, nBlue));
}
}
_currentBitmap = (Bitmap)bmap.Clone();
}
}