如何DrawImage
不丢失动画?
pictureBox1.Image = new Bitmap(20, 20);
Graphics g = Graphics.FromImage(pictureBox1.Image);
Image i = Properties.Resources.SuperMario; //Animated GIF; sprite; 20px X 20px
g.DrawImage(i,
new Rectangle(0, 0, 20, 20),
new Rectangle(0, 0, 20, 20),
GraphicsUnit.Pixel);
pictureBox1.Refresh();
以上代码,将动画精灵表(GIF格式)中的图像部分复制到PictureBox
'Image
。不幸的是,动画丢失了。
提前谢谢。
答案 0 :(得分:1)
您必须使用某种计时器/线程以正确的动画速率不断更新图像。 graphics.drawImage只在调用时绘制一次图像,它不理解动画。
如果你真的想使用这种动画方法,你应该保留一个变量来保存帧索引。删除表单上的Timer
组件,并将其设置为以动画制作动画的间隔触发。当计时器触发增加帧计数器时,然后清除,并使用新索引的帧边界重绘图片框。当它超出动画中的最大帧时,你应该将帧计数器包装回0。
答案 1 :(得分:1)
将整个gif加载到图片框中并将其定位,使得只有相关部分显示在图片框中。多数精灵是如何运作的。您不必复制特定帧的部分,因为是,这显然会丢失动画。
将图片框放在面板中,然后将图片框的位置设置为精灵元素的位置。
答案 2 :(得分:1)
PictureBox
天生就能理解动画GIF。
为什么需要在Update方法中手动绘制它?
创建PictureBox
就足够了,将动画GIF设置为Image
的{{1}}。
还要确保您不在GUI线程上运行任何阻止代码,因为这将阻止动画运行。
答案 3 :(得分:1)
您可以访问该链接获取源代码http://www.codeproject.com/KB/GDI-plus/NGif.aspx
答案 4 :(得分:1)
class WinForm : Form
{
bool FrameLoop = false;
int FrameIndex = 0;
int FrameCount = 0;
FrameDimension FrameDimension = null;
List<int> DelayTime = new List<int>();
Image img;
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
this.DoubleBuffered = true;
img = Image.FromFile("C:\\debug.gif");
if (img.FrameDimensionsList != null)
foreach (Guid i in img.FrameDimensionsList)
{
FrameDimension = new FrameDimension(i);
FrameCount = img.GetFrameCount(FrameDimension);
}
if (FrameCount > 1)
{
foreach (PropertyItem i in img.PropertyItems)
{
if (i.Id == 0x5100)
{
for (int j = 0; j < FrameCount; j++)
{
DelayTime.Add(BitConverter.ToInt32(i.Value, j * 4));
}
}
else if (i.Id == 0x5101)
{
FrameLoop = true;
}
}
this.BeginInvoke(new EventHandler(Animation));
}
}
private void Animation(object sender,EventArgs e)
{
img.SelectActiveFrame(FrameDimension, FrameIndex);
this.Refresh();
Application.DoEvents();
Thread.Sleep(DelayTime[FrameIndex] * 10);
FrameIndex++;
if (FrameIndex >= FrameCount)
{
if (FrameLoop)
FrameIndex = 0;
else
return;
}
Animation(sender, e);
}
protected override void OnPaint(PaintEventArgs e)
{
if (img == null)
return;
e.Graphics.DrawImage(img, new Point(0, 0));
//base.OnPaint(e);
}
}