如何在没有内存问题的情况下加载/操作巨大的图像?

时间:2012-11-18 21:00:40

标签: c# asp.net c#-4.0

尝试将巨大的图像(例如9000x9000像素图像)加载到Bitmap对象中会产生内存不足错误,"Parameter is not valid" error,毫无疑问会产生其他相关问题。

如何从磁盘加载9000x9000像素图像,最终在保存回磁盘之前调整其大小,而不会导致致命错误(例如内存不足)?

让我们假设一个32位环境,2GB内存,C#4.0,并将使用jpg,gif,bmp,tif,png等图像格式。

我尝试了以下3个片段,每个片段都因内存错误而失败。

尝试1:

using (Bitmap srcImg = new Bitmap(@"C:\9000x9000.jpg"))
{
    // boom
}

尝试2:

using (Image srcImg = Image.FromFile(@"C:\9000x9000.jpg"))
{
    // kapow
}

尝试3:

using (FileStream fs = new FileStream(@"C:\9000x9000.jpg", FileMode.Open, FileAccess.Read))
{
    using (Image srcImg = Image.FromStream(fs))
    {
        // kelly clarkson
    }
}

我想到一个可能的解决方案是将图像文件直接加载到一个数组中(这样你就不会有很大的Bitmap对象开销),不知何故使用该数组调整它的大小(可能需要为不同的图像编写代码)格式标题?),最后转换为可管理大小的Bitmap对象。

想法或可能的解决方案?

2 个答案:

答案 0 :(得分:1)

在处理大型文件时,请查看AForge.Net librarysupposedly good

答案 1 :(得分:0)

以下是我遵循的步骤:

1.转到http://www.opennetcf.org/PermaLink.aspx?guid=d57ace50-2762-4b19-b07d-39421829d410并下载下载SDF 2.0 Beta1可再发行组件。安装。

2.在面向PPC 2003 SE设备的VS.NET 2005中创建智能设备项目。我必须右键单击我的项目并选择“升级”以确保它的目标是.NET CF v2.0而不是.NET CF 1.1 SP3。

3.我从默认安装目录(C:\ Program Files \ OpenNETCF \ Smart Device Framework 2.0)中添加了OpenNETCF.dll和OpenNETCF.Drawing.dll文件作为参考

4.我在表单上创建了一个带有图片框的简单应用程序,在加载表单时加载我的图像。这是相关代码,其中一些是从Alex Feinman的网络日志中复制的:

#region Using directives
using System;
using System.Drawing;
using System.Collections;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using OpenNETCF.Drawing.Imaging;
using System.IO;
#endregion

....

const string szFileName = @"\Storage Card\TEMP\2MBJPEG.JPG";



private void Form1_Load(object sender, EventArgs e)
{
IBitmapImage imageBitmap;
FileStream fsImage;
fsImage = new FileStream(
    szFileName,
    FileMode.Open);
imageBitmap = CreateThumbnail(
    fsImage,
    new Size(100, 100));

Bitmap bm = ImageUtils.IBitmapImageToBitmap(
    imageBitmap);
pictureBox1.Image = bm;
}


static public IBitmapImage CreateThumbnail(Stream stream, Size size)
{
IBitmapImage imageBitmap;
ImageInfo ii;
IImage image;
ImagingFactory factory = new ImagingFactoryClass();
    factory.CreateImageFromStream(
    new StreamOnFile(stream), 
    out image);
image.GetImageInfo(out ii);
factory.CreateBitmapFromImage(
    image, 
    (uint)size.Width, 
    (uint)size.Height,
    ii.PixelFormat, 
    InterpolationHint.InterpolationHintDefault, 
    out imageBitmap);
    return imageBitmap;
}