我将图像存储在位图中。当我调整对象大小时,我的图像也需要调整大小。我已经做了一个功能,将我的图像调整到所需的大小。
当我绝对需要调整图像大小时,我已经只调用了这个函数,但是我不断地将这个图像大小的内存成本从50 MB迅速跳到1 GB以上。 (当按住鼠标按钮时,需要在每毫秒调用此方法。)
我在Graphics
中拥有using
但在这种情况下似乎没什么帮助。
如果我在其上调用GC.Collect(2)
当然有帮助,但它会极大地降低GUI的速度,如果我将其设置为非阻塞,那么它根本不会有任何帮助。
有没有办法释放被调用的此函数的最后一个实例仍未使用的内存,或者我是否需要更改我的代码并以另一种方式执行此操作?如果有更好的方式我会欣赏一些帮助,因为似乎GDI漏洞或我的方法效率很低。
我的代码:
public int getWidth()
{
return width;
}
public int getHeight()
{
return height;
}
public void createScaledImage()
{
var cr = new c_returnGraphicSettings();
if (getWidth() > 20 && getHeight() > 20)
{
scaledImage = new Bitmap(getWidth(), getHeight());
using (Graphics g = Graphics.FromImage(scaledImage))
{
/*
g.InterpolationMode = cr.getIM();
g.PixelOffsetMode = cr.getPOM();
g.SmoothingMode = cr.getSM();
/*--*/
g.DrawImage(image, new Rectangle(new Point(0, 0), scaledImage.Size), new Rectangle(new Point(0, 0), image.Size), GraphicsUnit.Pixel);
g.Dispose();
}
//GC.Collect(2, GCCollectionMode.Forced, true);
}
}
public Bitmap getScaledImage()
{
//createScaledImage();
return scaledImage;
}
public void resizeImage()
{
if(image != null)
{
createScaledImage();
}
}
主要表格的代码:
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
//TODO: PAINT!!
organizeImageList();
foreach (c_ImageHolder c in Limages)
{
if (c != null)
{
e.Graphics.DrawImage(c.getScaledImage(), c.Position);
...
}
}
}
private void f_Screen_MouseDown(object sender, MouseEventArgs e)
{
Limages.Sort(new intComparerDesc());
foreach (c_ImageHolder c in Limages)
{
if (renhan.pointInPosition(e.Location, new Rectangle(c.Position, c.Size)))
{
c.select();
selectedImage = c;
imageDragPoint = new Point(e.X - c.Left, e.Y - c.Top);
if (!c.isOverAnEdge(imageDragPoint) && !c.isOverACorner(imageDragPoint))
{
resize = false;
cResizer = null;
ed = edges.none;
cor = corners.none;
}
else
{
resize = true;
cResizer = c;
if (c.isOverAnEdge(imageDragPoint))
{
ed = c.overWhichEdge(imageDragPoint);
cor = corners.none;
}
else
{
cor = c.overWhichCorner(imageDragPoint);
ed = edges.none;
}
}
mdown = true;
break;
}
}
Invalidate();
}
说明:
我使用我制作的类来存储位图图像及其大小和位置的一些数据,然后我用它将该图像绘制到存储此类实例的屏幕上。
由于透明度问题,我没有使用控件(图片框等)。
每个实例包含不同的图像。我还需要能够调整这些图像的大小。出于这个原因,我有第二个位图,我存储原始位图的调整版本。
我使用不同的位图来存储已调整大小的图像,这样如果我需要再次调整大小,我就不会调整已经修改的图像的大小,而是调整原始图像的大小。 (保持质量)
调整大小如下: 我按住图像边缘上的鼠标按钮。当我每次调整大小时按住按钮的同时移动鼠标时,类会生成一个新图像,将原始图像拉伸到新尺寸上。将该图像返回到无效的主屏幕,并在绘制时将新图像绘制到屏幕背景上。
问题在于,由于我需要将此图像绘制到背景上,因此我无法处理它。我可以复印并处理原件,但我认为,那时候我也有同样的问题。
当我按住鼠标按钮并不断重新绘制图像时,内存会迅速增加。我完成后可以处理,但只要调整图像大小就可以使程序崩溃。
我制作了一个更简单,更简单的程序来演示我的问题以及您可以在这里找到的简短视频:Video and link to program
我的演示程序链接存储在Dropbox的视频下的rar文件中。
我希望这个解释和视频/演示有助于更好地解释我的问题。
感谢所有想要帮助的人!
答案 0 :(得分:0)
感谢所有试图提供帮助的人。我finalyl意识到我哪里出错了。
当我在控件中管理图像时,我保留了原始代码的功能。
使用我的新代码,我可以管理调整大小而无需将其写入新的位图。
我不知道为什么我不明白,就像5个人告诉我同样的事情。
再次感谢。