C#绘图放大缩小问题

cyxcw1 2010-11-12 11:40:34
运用GDI+绘图,比如点画线,点画矩形...
如何实现画出来这些图形的放大缩小功能,还要增加旋转,恢复的功能
...全文
1146 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
兔子-顾问 2010-11-17
  • 打赏
  • 举报
回复
简单点,你看msdn中Graphics.DrawImage就可以了。
复杂的就是用坐标转换。多种方式。你如果学GDI+,最不能错过的就是这个GDI+全面的范例了。
http://download.csdn.net/source/2090762
cyxcw1 2010-11-16
  • 打赏
  • 举报
回复
public class ImageViewer : UserControl
{
public Image Image = null;
// 从一个显示一个现有的Image对象
public void ShowImage(Image image)
{
this.Clear(false);

if (image == null)
{
this.Invalidate();
return;
}

this._image = image;
this._size.Width = image.Width;
this._size.Height = image.Height;

// 创建内存位图
this._memImage = new Bitmap((int)this._size.Width, (int)this._size.Height);
this._memGraphic = Graphics.FromImage(this._memImage);
this._memGraphic.DrawImage(this._image, 0, 0, this._size.Width, this._size.Height);

Image = _image;

this.Invalidate();
}

// 图片的原始大小
public void ZoomNormal()
{
this._size.Height = this._image.Height;
this._size.Width = this._image.Width;
this._anchor.X = 0;
this._anchor.Y = 0;
Invalidate();
}

// 放大图片. factor > 0 为放大, factor < 0 为缩小, =0 不变.
public void Zoom(int factor)
{
if (factor == 0)
return;

int zoomx = 0;
int zoomy = 0;

bool mouseInImage = this._mouse.X > this._anchor.X
&& this._mouse.X < this._anchor.X + this._size.Width
&& this._mouse.Y > this._anchor.Y
&& this._mouse.Y < this._anchor.Y + this._size.Height;

if (factor > 0)
{
zoomx = (int)(this._size.Width * this._delta);
zoomy = (int)(this._size.Height * this._delta);

// 如果鼠标在图片是, 以鼠标为中心放大, 此时调整anchor的位置
// 否则, 则按照窗口大小进行位置调整.
if (mouseInImage)
{
float adjx = (float)(this._mouse.X - this._anchor.X) / (float)this._size.Width;
float adjy = (float)(this._mouse.Y - this._anchor.Y) / (float)this._size.Height;
this._anchor.X -= (int)(adjx * zoomx);
this._anchor.Y -= (int)(adjy * zoomy);
}
this._size.Width = this._size.Width + zoomx;
this._size.Height = this._size.Height + zoomy;
}
else
{

if (this._size.Width < this.Width / 2 && this._size.Height < this.Height / 2)
return;

zoomx = (int)(this._size.Width * this._delta);
zoomy = (int)(this._size.Height * this._delta);

if (mouseInImage)
{
float adjx = (float)(this._mouse.X - this._anchor.X) / (float)this._size.Width;
float adjy = (float)(this._mouse.Y - this._anchor.Y) / (float)this._size.Height;

this._anchor.X += (int)(adjx * zoomx);
this._anchor.Y += (int)(adjy * zoomy);
}
this._size.Width = this._size.Width - zoomx;
this._size.Height = this._size.Height - zoomy;
}

Invalidate();
}

// 居中一个边框.
public void CenterRect(Rectangle rect)
{
this.Invalidate();
}

public void Clear(bool bPaint)
{
if (this._image == null)
return;

this._image = null;

if (this._memGraphic != null)
this._memGraphic.Dispose();
if (this._memImage != null)
this._memImage.Dispose();

this._memImage = null;
this._memGraphic = null;

this._anchor.X = 0;
this._anchor.Y = 0;

this._size.Height = 0;
this._size.Width = 0;

this.HotRect = RectangleF.Empty;

this._moving = false;
}

public RectangleF HotRect
{
get
{
return this._hotRect;
}
set
{
if (this._memImage == null)
return;
if (this.HotRect != RectangleF.Empty) // 回复原图像
{
this._memGraphic.DrawImage(this._image, this._hotRect, this._hotRect, GraphicsUnit.Pixel);
}
this._hotRect = value;
this._memGraphic.FillRectangle(this._hotBrsh, this._hotRect);
this.Invalidate();
}
}

public void CenterRect(RectangleF rect)
{
float x = (rect.Left + rect.Width - this.Width) / -2;
float y = (rect.Top + rect.Height - this.Height) / -2;

ScrollDataInfo(this._anchor.X - x, this._anchor.Y - y);
}

public void CenterAndHotRect(RectangleF rect)
{
if (this.HotRect != RectangleF.Empty) // 回复原图像
{
this._memGraphic.DrawImage(this._image, this._hotRect, this._hotRect, GraphicsUnit.Pixel);
}
this._hotRect = rect;
this._memGraphic.FillRectangle(this._hotBrsh, this._hotRect);
//float x = ( rect.Left + rect.Width - this.Width ) / -2;
//float y = ( rect.Top + rect.Height - this.Height ) / -2;
float x = rect.Left + rect.Width / 2 - this.Width / 2;
float y = rect.Top + rect.Height / 2 - this.Height / 2;
ScrollDataInfo(-x, -y);
this.Invalidate();
}

// 构造函数, 执行初始化工作.
public ImageViewer()
: base()
{
this._backBrush = new TextureBrush(Resource.BITMAP_BACKUP); // 背景画刷
this._anchor = new Point(0, 0); // 起始点坐标
}

protected override void OnPaint(PaintEventArgs e)
{
Rectangle clip = e.ClipRectangle;

if (this._memImage == null)
{
e.Graphics.FillRectangle(this._backBrush, clip);
return;
}

e.Graphics.DrawImage(this._memImage, this._anchor.X, this._anchor.Y,
this._size.Width, this._size.Height);

if (this._anchor.X > 0)
e.Graphics.FillRectangle(this._backBrush, 0, 0, this._anchor.X, Height);

if (this._anchor.Y > 0)
e.Graphics.FillRectangle(this._backBrush, 0, 0, Width, this._anchor.Y);

if (this._anchor.X + this._size.Width < this.Width)
e.Graphics.FillRectangle(
this._backBrush, this._anchor.X + this._size.Width,
Math.Max(this._anchor.Y, 0),
this.Width - this._anchor.X - this._size.Width,
this.Height
);

if (this._anchor.Y + this._size.Height < this.Height)
e.Graphics.FillRectangle(
this._backBrush, Math.Max(this._anchor.X, 0),
this._anchor.Y + this._size.Height,
this.Width,
this.Height - this._anchor.Y - this._size.Height
);
}

// 绘制窗口背景.
protected override void OnPaintBackground(PaintEventArgs e)
{
}

// 鼠标滚轮的事件相应.
protected override void OnMouseWheel(MouseEventArgs e)
{
if (e.Delta == 0)
return;
Zoom(e.Delta);
}

// 鼠标点击事件
protected override void OnMouseDown(MouseEventArgs e)
{
this.Select();
if (e.Button == MouseButtons.Left && this._image != null)
{
this._moving = true;
this._mouse.X = e.X;
this._mouse.Y = e.Y;
}
else
this._moving = false;
}

自己看看,这样方便
ctr54188 2010-11-13
  • 打赏
  • 举报
回复
看看学习了
zhuimeng11025 2010-11-13
  • 打赏
  • 举报
回复
你是想做画图程序吧
http://www.codeproject.com/KB/cs/DrawToolsRedux.aspx
看下这段源码
相信对你有帮助了
有问题可以互相探讨
cyxcw1 2010-11-12
  • 打赏
  • 举报
回复
求解答...
cyxcw1 2010-11-12
  • 打赏
  • 举报
回复
1楼
能说的更清楚些吗,我刚开始用GDI+,希望有个例子

我看BASIC有这个功能,但是我现在还没学
gaomeng320 2010-11-12
  • 打赏
  • 举报
回复
会有答案吗
duanzhi1984 2010-11-12
  • 打赏
  • 举报
回复
这个没用过,期待高手来啊。。
wjq 2010-11-12
  • 打赏
  • 举报
回复
1: 矢量绘图,记录点的相对坐标,根据需要的尺寸绘制
2:绘制到一个内存Image上,然后复制图片到另一个Image上,同时指定目标尺寸和缩放方式。
x89652 2010-11-12
  • 打赏
  • 举报
回复
不太会这放面的 待请教
xuzhx 2010-11-12
  • 打赏
  • 举报
回复
懒人! 非常简单的坐标计算而已,就是不愿动脑筋!

cyxcw1 2010-11-12
  • 打赏
  • 举报
回复
谢谢大家的回答了,我想那些代码会对我有用的
我仔细看看...嘿嘿
Fry_cici 2010-11-12
  • 打赏
  • 举报
回复
http://www.cnblogs.com/cloudgamer/archive/2010/04/14/ImageZoom_ext.html
Fry_cici 2010-11-12
  • 打赏
  • 举报
回复
zerodegrees 2010-11-12
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 cdglynn 的回复:]
C# code

// 鼠标抬起事件.
protected override void OnMouseUp(MouseEventArgs e)
{
this._moving = false;
}

protected override void OnMouseMove(Mouse……
[/Quote]
好长啊。。。
mabiJay 2010-11-12
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 cdglynn 的回复:]
C# code

// 鼠标抬起事件.
protected override void OnMouseUp(MouseEventArgs e)
{
this._moving = false;
}

protected override void OnMouseMove(Mouse……
[/Quote]


学习 ... ...
gavinmark 2010-11-12
  • 打赏
  • 举报
回复
学习了。UP
cdglynn 2010-11-12
  • 打赏
  • 举报
回复

// 鼠标抬起事件.
protected override void OnMouseUp(MouseEventArgs e)
{
this._moving = false;
}

protected override void OnMouseMove(MouseEventArgs e)
{
if (!this._moving)
return;

ScrollDataInfo(e.X - this._mouse.X, e.Y - this._mouse.Y);
this._mouse.X = e.X;
this._mouse.Y = e.Y;
}

// 键按下事件
protected override void OnKeyDown(KeyEventArgs e)
{
if (e.Control)
this._delta = this.DELTA_MAX;
else
this._delta = this.DELTA_MIN;
}

// 键弹起事件
protected override void OnKeyUp(KeyEventArgs e)
{
if (this._image == null) // 没有图像则退出
return;
if (e.Control)
this._delta = this.DELTA_MAX;
else
this._delta = this.DELTA_MIN;

// 翻转
if (e.KeyCode == Keys.PageDown)
{
this._memImage.RotateFlip(RotateFlipType.Rotate90FlipNone);
SwapDimension();
Invalidate();
}

if (e.KeyCode == Keys.PageUp)
{
this._memImage.RotateFlip(RotateFlipType.Rotate270FlipNone);
SwapDimension();
Invalidate();
}

// 回复原始尺寸
if (e.KeyCode == Keys.Home)
this.ZoomNormal();

// 适合窗口的大小
if (e.KeyCode == Keys.End)
{
this._anchor.X = 0;
this._anchor.Y = 0;
this._size.Height = this.Height;
this._size.Width = this.Width;
this.Invalidate();
}


}

// 滚动窗口图片
private void ScrollDataInfo(float DX, float DY)
{
DX = CalcDelta(DX, this._anchor.X, this._size.Width, this.Width);
DY = CalcDelta(DY, this._anchor.Y, this._size.Height, this.Height);

if (DX == 0 && DY == 0)
return;

this.Invalidate();

this._anchor.X += DX;
this._anchor.Y += DY;
}


// 计算Delta的值
private float CalcDelta(float delta, float anchor, float size, float extend)
{
if (delta == 0)
return delta;

if (size > extend)
{
if (delta > 0)
if (anchor + delta > 0)
if (anchor == 0)
return 0;
else
return anchor * -1;
else
return delta;

if (anchor + delta < extend - size)
if (anchor == extend - size)
return 0;
else
return extend - size - anchor;
else
return delta;
}
else
{
if (delta > 0)
if (anchor + delta > extend - size)
if (anchor == extend - size)
return 0;
else
return extend - size - anchor;
else
return delta;

if (anchor + delta < 0)
if (anchor == 0)
return 0;
else
return anchor * -1;
else
return delta;
}
}

// 翻转图像的长宽
private void SwapDimension()
{
float i = this._size.Height;
this._size.Height = this._size.Width;
this._size.Width = i;
}

private TextureBrush _backBrush = null; // 背景画刷
private PointF _anchor; // 当前图片的左上角坐标
private PointF _mouse; // 当前鼠标的位置.
private bool _moving = false; // 正在移动图像
private float _delta = 0.1F; // 放大速度.
private SizeF _size = Size.Empty; // 图像的大小
private Image _image = null; // 显示的图片
private RectangleF _hotRect; // 当前的高亮矩形.
private Brush _hotBrsh = new SolidBrush(Color.FromArgb(50, Color.Blue));

private Image _memImage;
private Graphics _memGraphic;

private float DELTA_MAX = 0.3F; // 最大缩放比
private float DELTA_MIN = 0.1F; // 最小缩放比
}
cdglynn 2010-11-12
  • 打赏
  • 举报
回复
呵呵,希望你多动动脑筋,本想围观,程序员都不容易,还是给你个代码吧(效率不高)
[code=C#]public class ImageViewer : UserControl
{
public Image Image = null;
// 从一个显示一个现有的Image对象
public void ShowImage(Image image)
{
this.Clear(false);

if (image == null)
{
this.Invalidate();
return;
}

this._image = image;
this._size.Width = image.Width;
this._size.Height = image.Height;

// 创建内存位图
this._memImage = new Bitmap((int)this._size.Width, (int)this._size.Height);
this._memGraphic = Graphics.FromImage(this._memImage);
this._memGraphic.DrawImage(this._image, 0, 0, this._size.Width, this._size.Height);

Image = _image;

this.Invalidate();
}

// 图片的原始大小
public void ZoomNormal()
{
this._size.Height = this._image.Height;
this._size.Width = this._image.Width;
this._anchor.X = 0;
this._anchor.Y = 0;
Invalidate();
}

// 放大图片. factor > 0 为放大, factor < 0 为缩小, =0 不变.
public void Zoom(int factor)
{
if (factor == 0)
return;

int zoomx = 0;
int zoomy = 0;

bool mouseInImage = this._mouse.X > this._anchor.X
&& this._mouse.X < this._anchor.X + this._size.Width
&& this._mouse.Y > this._anchor.Y
&& this._mouse.Y < this._anchor.Y + this._size.Height;

if (factor > 0)
{
zoomx = (int)(this._size.Width * this._delta);
zoomy = (int)(this._size.Height * this._delta);

// 如果鼠标在图片是, 以鼠标为中心放大, 此时调整anchor的位置
// 否则, 则按照窗口大小进行位置调整.
if (mouseInImage)
{
float adjx = (float)(this._mouse.X - this._anchor.X) / (float)this._size.Width;
float adjy = (float)(this._mouse.Y - this._anchor.Y) / (float)this._size.Height;
this._anchor.X -= (int)(adjx * zoomx);
this._anchor.Y -= (int)(adjy * zoomy);
}
this._size.Width = this._size.Width + zoomx;
this._size.Height = this._size.Height + zoomy;
}
else
{

if (this._size.Width < this.Width / 2 && this._size.Height < this.Height / 2)
return;

zoomx = (int)(this._size.Width * this._delta);
zoomy = (int)(this._size.Height * this._delta);

if (mouseInImage)
{
float adjx = (float)(this._mouse.X - this._anchor.X) / (float)this._size.Width;
float adjy = (float)(this._mouse.Y - this._anchor.Y) / (float)this._size.Height;

this._anchor.X += (int)(adjx * zoomx);
this._anchor.Y += (int)(adjy * zoomy);
}
this._size.Width = this._size.Width - zoomx;
this._size.Height = this._size.Height - zoomy;
}

Invalidate();
}

// 居中一个边框.
public void CenterRect(Rectangle rect)
{
this.Invalidate();
}

public void Clear(bool bPaint)
{
if (this._image == null)
return;

this._image = null;

if (this._memGraphic != null)
this._memGraphic.Dispose();
if (this._memImage != null)
this._memImage.Dispose();

this._memImage = null;
this._memGraphic = null;

this._anchor.X = 0;
this._anchor.Y = 0;

this._size.Height = 0;
this._size.Width = 0;

this.HotRect = RectangleF.Empty;

this._moving = false;
}

public RectangleF HotRect
{
get
{
return this._hotRect;
}
set
{
if (this._memImage == null)
return;
if (this.HotRect != RectangleF.Empty) // 回复原图像
{
this._memGraphic.DrawImage(this._image, this._hotRect, this._hotRect, GraphicsUnit.Pixel);
}
this._hotRect = value;
this._memGraphic.FillRectangle(this._hotBrsh, this._hotRect);
this.Invalidate();
}
}

public void CenterRect(RectangleF rect)
{
float x = (rect.Left + rect.Width - this.Width) / -2;
float y = (rect.Top + rect.Height - this.Height) / -2;

ScrollDataInfo(this._anchor.X - x, this._anchor.Y - y);
}

public void CenterAndHotRect(RectangleF rect)
{
if (this.HotRect != RectangleF.Empty) // 回复原图像
{
this._memGraphic.DrawImage(this._image, this._hotRect, this._hotRect, GraphicsUnit.Pixel);
}
this._hotRect = rect;
this._memGraphic.FillRectangle(this._hotBrsh, this._hotRect);
//float x = ( rect.Left + rect.Width - this.Width ) / -2;
//float y = ( rect.Top + rect.Height - this.Height ) / -2;
float x = rect.Left + rect.Width / 2 - this.Width / 2;
float y = rect.Top + rect.Height / 2 - this.Height / 2;
ScrollDataInfo(-x, -y);
this.Invalidate();
}

// 构造函数, 执行初始化工作.
public ImageViewer()
: base()
{
this._backBrush = new TextureBrush(Resource.BITMAP_BACKUP); // 背景画刷
this._anchor = new Point(0, 0); // 起始点坐标
}

protected override void OnPaint(PaintEventArgs e)
{
Rectangle clip = e.ClipRectangle;

if (this._memImage == null)
{
e.Graphics.FillRectangle(this._backBrush, clip);
return;
}

e.Graphics.DrawImage(this._memImage, this._anchor.X, this._anchor.Y,
this._size.Width, this._size.Height);

if (this._anchor.X > 0)
e.Graphics.FillRectangle(this._backBrush, 0, 0, this._anchor.X, Height);

if (this._anchor.Y > 0)
e.Graphics.FillRectangle(this._backBrush, 0, 0, Width, this._anchor.Y);

if (this._anchor.X + this._size.Width < this.Width)
e.Graphics.FillRectangle(
this._backBrush, this._anchor.X + this._size.Width,
Math.Max(this._anchor.Y, 0),
this.Width - this._anchor.X - this._size.Width,
this.Height
);

if (this._anchor.Y + this._size.Height < this.Height)
e.Graphics.FillRectangle(
this._backBrush, Math.Max(this._anchor.X, 0),
this._anchor.Y + this._size.Height,
this.Width,
this.Height - this._anchor.Y - this._size.Height
);
}

// 绘制窗口背景.
protected override void OnPaintBackground(PaintEventArgs e)
{
}

// 鼠标滚轮的事件相应.
protected override void OnMouseWheel(MouseEventArgs e)
{
if (e.Delta == 0)
return;
Zoom(e.Delta);
}

// 鼠标点击事件
protected override void OnMouseDown(MouseEventArgs e)
{
this.Select();
if (e.Button == MouseButtons.Left && this._image != null)
{
this._moving = true;
this._mouse.X = e.X;
this._mouse.Y = e.Y;
}
else
this._moving = false;
}
code]

111,129

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Creator Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧