在没有内存不足的情况下在c#中加载1000个图像 [英] load 1000 images in c# without out-of-memory exception

查看:156
本文介绍了在没有内存不足的情况下在c#中加载1000个图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在桌面应用程序中的运行时在面板中添加1000个图像(每个大小为(40到100)KB)。首先,用户浏览所有图像并将其加载到面板上。当它一个接一个地加载图像时,任务管理器中显示的内存使用量迅速增加,并且在一定数量的图像之后它显示内存不足。我的代码中的错误在哪里?



在加载700图像之前,任务管理器显示1.05 GB的内存使用量。加载任务管理器后显示2.04 GB和2 GB RAM溢出

 int picnumber = 0; 
int numberOfImages = 1000;


for(int i = 0; i< numberOfImages; i ++)
{
GroupBox gBox = new GroupBox();

picnumber ++;


////////////////////////////////

//计算放置它的组合框的位置。
if((picnumber%3)== 1)
{
x = initX;
}
其他
{
if((picnumber%3)== 0)
{
x = initX + 2 *(130 + 20);
}
其他
{
x = initX + 130 + 20;
}

}
//////////////////////////////// ///


System.Drawing.Point CurrentPoint;

CurrentPoint = panel1.AutoScrollPosition;
y = initY +((picnumber - 1)/ 3)*(130 + 20) - (Math.Abs​​(panel1.AutoScrollPosition.Y));

gBox.Text = picnumber.ToString();

//将组合框放在适当的位置。
gBox.Location = new System.Drawing.Point(x,y);
gBox.Size = new System.Drawing.Size(130,130);

位图btmap =新位图(@E:\\\ n.jpg);
//将图像附加到groupbox
gBox.BackgroundImage = btmap;
gBox.BackgroundImageLayout = ImageLayout.Stretch;
//将包含图像的组框添加到面板。
panel1.Controls.Add(gBox);





但我看到一些应用程序可以加载大量图像并占用可忽略不计的内存,例如Batch Image Resizer(http://www.jklnsoft.com/)



在加载700个图像之前,任务管理器显示1.05 GB的内存使用量。加载任务管理器后显示1.06 GB

应用程序如何处理内存?他们遵循什么机制?

开发环境:C#.net框架4,windows xp,Visual Studio 2010,RAM:2 GB

解决方案

他们不这样做 - 他们只绘制用户看到的图像 - 他们在任何时候都不会加载1000张图像并希望它能够正常工作。他们可能做的最多是加载图像,拍摄一个小缩略图,然后卸载图像。然后可以根据用户需要显示缩略图。您试图保留1000个位图,每个位图都比较大!


关于OriginalGriff的答案,这里是调整图像大小或创建缩略图的代码:



  public   class 工具
{
public static Image ResizeImage(Image imgToResize,Size size)
{
int sourceWidth = imgToResize.Width;
int sourceHeight = imgToResize.Height;

float nPercent = 0 ;
float nPercentW = 0 ;
float nPercentH = 0 ;

nPercentW =(( float )size.Width /( float )sourceWidth );
nPercentH =(( float )size.Height /( float )sourceHeight);

if (nPercentH < nPercentW)
nPercent = nPercentH ;
else
nPercent = nPercentW;

int destWidth =( int )(sourceWidth * nPercent);
int destHeight =( int )(sourceHeight * nPercent);

位图b = new 位图(destWidth,destHeight);
图形g = Graphics.FromImage((图像)b);
g.InterpolationMode = InterpolationMode.HighQualityBicubic;

g.DrawImage(imgToResize, 0 0 ,destWidth,destHeight) ;
g.Dispose();

return (图片)b;
}
}





您可能需要将缩略图保存为临时文件,并仅在需要时检索它它不会让它挂在用户的记忆中。



希望这会有所帮助。


你可以尝试这个..



1)同时你不需要加载所有1000个图像...

2)你只能加载部分图像用户可以一次看到..

3)因为它会滚动或更改屏幕卸载以前的图像并加载新图像

4)所以你的内存问题将得到解决...

I want to add 1000 images (each size is (40 to 100) KB) in a panel at run time in a desktop application. At first user browses all the images and load them on a panel. When it loads images one after another then memory usage shown in the task manager increases rapidly and after a certain number of images it shows the "Out of Memory Exception". Where is the fault in my code?

Before loading the 700 images task manager shows 1.05 GB memory usage. After loading task manager shows 2.04 GB and 2 GB RAM overflows

int picnumber = 0;
int numberOfImages = 1000;


for (int i = 0; i < numberOfImages; i++)
{
    GroupBox gBox = new GroupBox();

    picnumber++;


    ////////////////////////////////

    // calculate the position of the groupbox where it is placed.
    if ((picnumber % 3) == 1)
    {
        x = initX;
    }
    else
    {
        if ((picnumber % 3) == 0)
        {
            x = initX + 2 * (130 + 20);
        }
        else
        {
            x = initX + 130 + 20;
        }

    }
    ///////////////////////////////////


    System.Drawing.Point CurrentPoint;

    CurrentPoint = panel1.AutoScrollPosition;
    y = initY + ((picnumber - 1) / 3) * (130 + 20) - (Math.Abs(panel1.AutoScrollPosition.Y));

    gBox.Text = picnumber.ToString();

    //place the groupbox in the appropriate position.
    gBox.Location = new System.Drawing.Point(x, y);
    gBox.Size = new System.Drawing.Size(130, 130);

    Bitmap btmap = new Bitmap(@"E:\43.jpg");
    // attach the image to the groupbox
    gBox.BackgroundImage = btmap;
    gBox.BackgroundImageLayout = ImageLayout.Stretch;
    // add the groupbox that contains image to the panel.
    panel1.Controls.Add(gBox);



But I have seen some applications that can load huge number of images and takes memory that is negligible, for example, "Batch Image Resizer"( http://www.jklnsoft.com/)

Before loading the 700 images task manager shows 1.05 GB memory usage. After loading task manager shows 1.06 GB
How does the application handle memory? What mechanism do they follow?
Development environment: C#.net framework 4, windows xp, Visual Studio 2010, RAM: 2 GB

解决方案

They don't do it like that - they draw only the images that the user sees - at no time do they load 1000 images and hope it will work. The most they might do is load the image, take a small thumbnail of it, and unload the image. The thumbnails are then available for display as the user needs them. You are trying to keep 1000 bitmaps, each huge in comparison!


In relation to OriginalGriff's answer, here is the code for resizing the images or creating thumbnails:

public class Tools
{
    public static Image ResizeImage(Image imgToResize, Size size)
    {
        int sourceWidth = imgToResize.Width;
        int sourceHeight = imgToResize.Height;

        float nPercent = 0;
        float nPercentW = 0;
        float nPercentH = 0;

        nPercentW = ((float)size.Width / (float)sourceWidth);
        nPercentH = ((float)size.Height / (float)sourceHeight);

        if (nPercentH < nPercentW)
            nPercent = nPercentH;
        else
            nPercent = nPercentW;

        int destWidth = (int)(sourceWidth * nPercent);
        int destHeight = (int)(sourceHeight * nPercent);

        Bitmap b = new Bitmap(destWidth, destHeight);
        Graphics g = Graphics.FromImage((Image)b);
        g.InterpolationMode = InterpolationMode.HighQualityBicubic;

        g.DrawImage(imgToResize, 0, 0, destWidth, destHeight);
        g.Dispose();

        return (Image)b;
    }
}



You might need to save the thumbnails as temporary files and retrieve it only when you need it instead of leaving it hanging on the user's memory.

Hope this helps.


you can try this..

1) at a same time you need not load the all 1000 images...
2) you can load only part of images that will user can see at a time..
3) as it will scroll or change the screen unload previous images and load new images
4) so you memory issue will be solved...


这篇关于在没有内存不足的情况下在c#中加载1000个图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆